Skip to content

fix: make jline-terminal-ffm a Multi-Release JAR to fix Java 17 boot layer failure - #2285

Merged
gnodet merged 1 commit into
jline:masterfrom
gnodet:fix/2284-ffm-multi-release-jar
Sep 23, 2026
Merged

gnodet merged 1 commit into
jline:masterfrom
gnodet:fix/2284-ffm-multi-release-jar

Conversation

@gnodet

@gnodet gnodet commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

Problem

jline-terminal-ffm had its module-info.class compiled at Java 22 (major version 66) placed at the root of the jar. When this jar was on the module path in a project using Java 17, the JVM failed during boot layer initialization:

Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: jline-terminal-ffm-4.4.3.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: Unsupported major.minor version 66.0

Fix

Convert jline-terminal-ffm into a proper Multi-Release JAR:

  1. Move module-info.java from src/main/java/ to src/main/java22/, a separate source root compiled with <multiReleaseOutput>true</multiReleaseOutput>, which places module-info.class in META-INF/versions/22/ instead of the jar root.
  2. Add Multi-Release: true to MANIFEST.MF via maven-jar-plugin.
  3. Switch the surefire argLine from --enable-native-access=org.jline.terminal.ffm to --enable-native-access=ALL-UNNAMED, since without a root module-info.class the test JVM no longer resolves the named module on the module path (this does not affect production use — the module is resolved correctly by consumers that use JPMS).

Result

  • Java 17+ projects that have jline-terminal-ffm on the module path no longer fail at boot layer initialization.
  • Java 22+ consumers continue to load the proper JPMS module descriptor from META-INF/versions/22/.
  • All 11 existing tests pass (1 skipped as before).

Fixes #2284.

Summary by CodeRabbit

  • New Features
    • The terminal package now includes Java 22-specific code in a multi-release archive. Java can select the appropriate implementation at runtime, while the package continues to support its existing Java versions. This improves compatibility for applications using the terminal component on Java 22 without requiring a separate package.

…layer failure (fixes jline#2284)

The module-info.class for jline-terminal-ffm was compiled at Java 22
(class file major version 66) and placed at the jar root. When the jar
was on the module path in a project that compiled or ran on Java 17,
the JVM failed during boot layer initialization with:

  Error occurred during initialization of boot layer
  java.lang.module.FindException: Error reading module: jline-terminal-ffm-X.Y.Z.jar
  Caused by: java.lang.module.InvalidModuleDescriptorException: Unsupported major.minor version 66.0

The fix converts jline-terminal-ffm into a proper Multi-Release JAR:
- Move module-info.java from src/main/java/ to src/main/java22/, a
  separate source root compiled with multiReleaseOutput=true, placing
  module-info.class in META-INF/versions/22/ instead of the jar root.
- Add Multi-Release: true to MANIFEST.MF via maven-jar-plugin.
- Switch the surefire argLine from --enable-native-access=org.jline.terminal.ffm
  to --enable-native-access=ALL-UNNAMED, since without a root module-info
  the test JVM no longer resolves the module on the module path.
@gnodet gnodet added the bug label Sep 23, 2026
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 8559cce1-5eb8-4fd8-bd99-c0301345b106

📥 Commits

Reviewing files that changed from the base of the PR and between 2e88bc9 and 6b21f96.

📒 Files selected for processing (2)
  • terminal-ffm/pom.xml
  • terminal-ffm/src/main/java22/module-info.java

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The terminal-ffm Maven configuration compiles Java 22 sources as multi-release output, marks the JAR as multi-release, and changes the Surefire native-access option.

Changes

FFM JAR Build

Layer / File(s) Summary
Multi-release compilation and packaging
terminal-ffm/pom.xml
The compiler plugin compiles sources from src/main/java22 with multiReleaseOutput enabled. The JAR manifest declares Multi-Release: true.
Surefire native access
terminal-ffm/pom.xml
Surefire changes its native-access option from --enable-native-access=org.jline.terminal.ffm to --enable-native-access=ALL-UNNAMED.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 6b21f

The supplied evidence does not identify a merge-blocking issue with the multi-release JAR change.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: making jline-terminal-ffm a Multi-Release JAR to resolve the Java 17 boot-layer failure.
Linked Issues check ✅ Passed The change addresses [#2284]. The maven-compiler-plugin compiles src/main/java22/module-info.java with multiReleaseOutput enabled. The maven-jar-plugin adds Multi-Release: true. The existing…
Out of Scope Changes check ✅ Passed The changes are limited to terminal-ffm/pom.xml. The compiler configuration and manifest entry implement [#2284]. The ALL-UNNAMED Surefire option supports test execution for the changed module pac…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gnodet gnodet added this to the 4.4.6 milestone Sep 23, 2026
@sonarqubecloud

Copy link
Copy Markdown

@gnodet
gnodet marked this pull request as ready for review September 23, 2026 11:03

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Textbook Multi-Release JAR fix — the implementation is correct end-to-end.

What was verified:

  • multiReleaseOutput=true + compileSourceRoots pointing to src/main/java22/ is the correct pattern for maven-compiler-plugin 3.16.0; module-info.class will land in META-INF/versions/22/ as intended.
  • Maven plugin config inheritance: the child <configuration> for maven-jar-plugin merges with the parent pluginManagement entry — manifestFile (Felix bundle MANIFEST.MF) and Automatic-Module-Name are inherited intact; Multi-Release: true is added on top. No OSGi headers lost.
  • --enable-native-access=ALL-UNNAMED is correct for surefire (classpath mode, no root module-info.class → no named module resolvable). Production consumers on the module path still load the JPMS descriptor from META-INF/versions/22/. The module-info.java Javadoc still correctly documents --enable-native-access=org.jline.terminal.ffm for production use.
  • CI passes green across all 9 platform/JDK combinations. SonarCloud: 0 new issues.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@gnodet
gnodet merged commit 2ab1d06 into jline:master Sep 23, 2026
15 checks passed
@gnodet
gnodet deleted the fix/2284-ffm-multi-release-jar branch September 23, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

jline-terminal-ffm: module-info.class compiled with Java 22 at jar root breaks Java 17 boot layer initialization

2 participants