Skip to content

fix(run): honor manifest launcher flags#2439

Merged
maxandersen merged 3 commits intojbangdev:mainfrom
ayagmar:fix/2366-2438-manifest-attrs
Mar 29, 2026
Merged

fix(run): honor manifest launcher flags#2439
maxandersen merged 3 commits intojbangdev:mainfrom
ayagmar:fix/2366-2438-manifest-attrs

Conversation

@ayagmar
Copy link
Copy Markdown
Contributor

@ayagmar ayagmar commented Mar 27, 2026

Fixes #2366 and #2438.

JBang runs jars with -classpath ... Main instead of java -jar, so manifest launcher entries were being ignored. This change reads the relevant values from the primary jar manifest and passes the equivalent JVM flags when JBang launches the jar

That means:

  • Add-Opens -> --add-opens=...=ALL-UNNAMED
  • Add-Exports -> --add-exports=...=ALL-UNNAMED
  • Enable-Native-Access: ALL-UNNAMED -> --enable-native-access=ALL-UNNAMED

This also fixes a bug where Add-Opens was being read from the wrong manifest value.

Added regression tests for the Add-Opens and Enable-Native-Access cases.

Not included : the separate classpath duplication issue mentioned in #2438.

maxandersen added a commit to maxandersen/jbang that referenced this pull request Mar 28, 2026
…butes

Extends manifest attribute support for jars beyond PR jbangdev#2439 to handle
Add-Reads module dependencies and SplashScreen-Image extraction.

Changes:
- Add Project.ATTR_ADD_READS and Project.ATTR_SPLASH_SCREEN_IMAGE constants
- Import Add-Reads and SplashScreen-Image attributes from jar manifests
- Process Add-Reads: converts to --add-reads JVM flags (Java 9+)
- Process SplashScreen-Image: extracts image and passes -splash flag
- Fix KeyValue.of() to support values containing '=' signs

Add-Reads implementation:
- Parses space-separated module dependencies (e.g., "mod1=mod2 mod3=mod4")
- Generates --add-reads flags for each dependency pair
- Version-gated for Java 9+ with runAsModule check

SplashScreen-Image implementation:
- Extracts splash image from jar to <jarPath>.splash.<ext> in cache
- Smart caching: only re-extracts if jar is newer than cached image
- Fails gracefully with warnings (never breaks the build)
- Adds -splash:<path> flag before other JVM options

KeyValue parser fix:
- Changed split("=") to split("=", 2) to handle values with '='
- Enables manifest directives like //MANIFEST Add-Reads=mod1=mod2

This builds on PR jbangdev#2439's copyManifestAttribute() and
addAllUnnamedManifestOptions() patterns.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
maxandersen added a commit to maxandersen/jbang that referenced this pull request Mar 28, 2026
…butes

Extends manifest attribute support for jars beyond PR jbangdev#2439 to handle
Add-Reads module dependencies and SplashScreen-Image extraction.

Changes:
- Add Project.ATTR_ADD_READS and Project.ATTR_SPLASH_SCREEN_IMAGE constants
- Import Add-Reads and SplashScreen-Image attributes from jar manifests
- Process Add-Reads: converts to --add-reads JVM flags (Java 9+)
- Process SplashScreen-Image: extracts image and passes -splash flag
- Fix KeyValue.of() to support values containing '=' signs

Add-Reads implementation:
- Parses space-separated module dependencies (e.g., "mod1=mod2 mod3=mod4")
- Generates --add-reads flags for each dependency pair
- Version-gated for Java 9+ with runAsModule check

SplashScreen-Image implementation:
- Extracts splash image from jar to <jarPath>.splash.<ext> in cache
- Smart caching: only re-extracts if jar is newer than cached image
- Fails gracefully with warnings (never breaks the build)
- Adds -splash:<path> flag before other JVM options

KeyValue parser fix:
- Changed split("=") to split("=", 2) to handle values with '='
- Enables manifest directives like //MANIFEST Add-Reads=mod1=mod2

This builds on PR jbangdev#2439's copyManifestAttribute() and
addAllUnnamedManifestOptions() patterns.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
maxandersen added a commit to maxandersen/jbang that referenced this pull request Mar 28, 2026
… helper methods

- Replace copyManifestAttribute() and addAllUnnamedManifestOptions() with inline code
- These helper methods are from PR jbangdev#2439 which is not yet merged
- Use the same pattern that exists in main branch
- Add missing imports for JarOutputStream, Manifest, and assumeTrue in tests
- Fix test code to use correct CmdGenerator.builder() pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
optionalArgs.add("--add-opens=" + val + "=ALL-UNNAMED");
}
}
if (!runAsModule && jdk.majorVersion() >= 9) {
Copy link
Copy Markdown
Collaborator

@maxandersen maxandersen Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is not runAsModule a requirement here ? add-opens and add-exports still apply wether it is run as a module or not is it not?

Got example where this will be wrong/fail?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for that that's my mistake. I don’t really have a real case to justify the runAsModule guard, so I’ll remove it

Copy link
Copy Markdown
Collaborator

@maxandersen maxandersen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall direction is good!

But not following why run-as-module should affect these settings; if its related to module-info presence then I would like example/test of what breaks/fails

and jbang should not fail on attributes it does not know if java -jar would not fail so need that to be gracefully handled or shown case where -jar would fail

@ayagmar ayagmar force-pushed the fix/2366-2438-manifest-attrs branch from 8ab21ec to b10580d Compare March 28, 2026 11:13
@ayagmar ayagmar force-pushed the fix/2366-2438-manifest-attrs branch from b10580d to e35dd51 Compare March 28, 2026 11:20
@ayagmar ayagmar requested a review from maxandersen March 28, 2026 11:20
@ayagmar
Copy link
Copy Markdown
Contributor Author

ayagmar commented Mar 28, 2026

overall direction is good!

But not following why run-as-module should affect these settings; if its related to module-info presence then I would like example/test of what breaks/fails

and jbang should not fail on attributes it does not know if java -jar would not fail so need that to be gracefully handled or shown case where -jar would fail

Thanks for the review @maxandersen
The runAsModule restriction was my fault, I dropped that guard in the latest push since I don't have a reproducer or example
Regarding the java-jar failing I attached sources on the comment above

Changes:
- Replace validation with pass-through for Enable-Native-Access
  - Let JVM validate values instead of JBang
  - Consistent with how we handle Add-Opens/Add-Exports
  - Simpler code, future-proof if spec changes

- Add addManifestOptions() helper
  - Similar to addAllUnnamedManifestOptions but without =ALL-UNNAMED suffix
  - Used for Enable-Native-Access which passes values directly

- Update tests:
  - Replace testRejectsInvalidEnableNativeAccess with testPassesThroughEnableNativeAccessModuleName
  - Add testReadingAddExportsWithHelper (using new createJar() helper)
  - Add edge case tests:
    * testEmptyManifestAttributeIgnored (whitespace-only values)
    * testMultipleSpacesBetweenValues (multiple spaces between values)
    * testMultipleModulesForEnableNativeAccess (space-separated module list)

- Add documentation:
  - New "JAR Manifest Attributes" section in running.adoc
  - Documents Add-Opens, Add-Exports, Enable-Native-Access
  - Explains how values are passed to JVM
  - Links to JAR spec and JEP 472
  - References issue jbangdev#2441 for --ignore-manifest flag

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@maxandersen maxandersen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i changed to simple passthrough for now to let javac complain + added tests/docs

@maxandersen
Copy link
Copy Markdown
Collaborator

@all-contributors add @@ayagmar for code

@allcontributors
Copy link
Copy Markdown
Contributor

@maxandersen

Could not find the user @ayagmar on github.

@maxandersen
Copy link
Copy Markdown
Collaborator

https://github.com/all-contributors add @ayagmar for code

@maxandersen maxandersen merged commit 32568d1 into jbangdev:main Mar 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

jbang run <jarFile> ignores Enable-Native-Access property in the manifest.mf file

2 participants