Skip to content

Honor --release for current JDK - #5254

Open
wilx wants to merge 1 commit into
eclipse-jdt:masterfrom
wilx:honor-release-current-jdk-modules
Open

Honor --release for current JDK#5254
wilx wants to merge 1 commit into
eclipse-jdt:masterfrom
wilx:honor-release-current-jdk-modules

Conversation

@wilx

@wilx wilx commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What it does

ECJ now applies the JEP 247 API restrictions when --release targets the same version as the JDK running the compiler.

Previously, this case bypassed ct.sym and used the live JRT image directly, which made implementation-specific modules observable. The change reads the current release system-modules metadata from ct.sym, uses the live JRT classes as intended, and filters class, module, and package lookup to the documented module set.

This aligns ECJ with javac and prevents modules such as OpenJ9 openj9.criu or HotSpot jdk.internal.vm.ci from being exposed through --release. The OpenJ9 behavior was reported in eclipse-openj9/openj9#18205 and diagnosed as an ECJ same-release issue in my comment on that issue.

The regression tests verify both that the current-release path uses ct.sym metadata and that an implementation-specific module available without --release is rejected when --release is present.

AI assistance: OpenAI Codex (GPT-5) helped investigate, implement, test, and prepare this change; the assistance is also recorded in the commit trailer.

How to test

  • Run BatchCompilerTest on a JDK that contains jdk.internal.vm.ci.
  • Verify that testReleaseCurrentJdkUsesCtSym selects the JEP 247 classpath for --release <current>.
  • Verify that testReleaseCurrentJdkFiltersImplementationSpecificModules accepts jdk.internal.vm.ci without --release and rejects it with --release <current>.
  • The focused BatchCompilerTest suite passed on Temurin 21: 370 tests, 0 failures, 0 errors, and 0 skipped tests.
  • git diff --check passes.

Author checklist

@wilx
wilx marked this pull request as ready for review July 30, 2026 11:38
Use ct.sym metadata to filter the live JRT image when --release targets
the running JDK. This prevents implementation-specific modules from
leaking through the standard API view.

Assisted-by: OpenAI Codex (GPT-5)
@wilx
wilx force-pushed the honor-release-current-jdk-modules branch from b381708 to 65d1f54 Compare August 1, 2026 00:15
@stephan-herrmann

Copy link
Copy Markdown
Contributor

I don't see ct.sym as a means to separate public from private modules. Cf. the title of JEP 247: "Compile for Older Platform Versions".

Question: is your use case about modular or non-modular client code? For the latter, it's JEP 261 that decides what is observable and what is not.

Actually, JEP 247 is quite specific about this:

Implementation

For JDK N and --release M, M < N, signature data of the documented APIs of release M of the platform is needed. This data is stored in the $JDK_ROOT/lib/ct.sym file, which is similar, but not the same, as the file of the same name in JDK 8. The ct.sym file is a ZIP file containing stripped-down class files corresponding to class files from the target platform versions.

For JDK N and --release N,the JDK's own image is used as the source of the class files to compile against. The list of observable modules is limited, however, to the documented modules and the jdk.unsupported module.

So, to resolve this issue, we'd need to figure out what "documented modules" are - documented where and how? Is there a relationship to JEP 261's "default set of root modules for the unnamed module"?

Also note that JEP 247 is not an official feature of Java SE, which is also the reason why it is scarcely documented.

@wilx

wilx commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

My motivation was the reported disparity between ECJ and javac when handling --release. The --release clearly is meant to restrict what you can use and whether we call it "documented modules" or something else, vendor specific modules are, IMHO, out of scope with this switch.

I think that "documented modules" is basically this

# Modules that should be visible for 9 - the documented modules:
CT_MODULES := $(DOCS_MODULES)

The names flow into the processing and eventually to ct.sym.

The test uses the --add-module only to test that it is not available with --release.

I think JEP 261 applies after JEP 247 has restricted the set.

@stephan-herrmann

Copy link
Copy Markdown
Contributor

My motivation was the reported disparity between ECJ and javac when handling --release.

That's great and I am all for eliminating such differences -- based on official specifications, where humanly possible.

The --release clearly is meant to restrict what you can use

You are right, and I admit that until today I hadn't seen that JEP 247 says "The list of observable modules is limited, however, to the documented modules and the jdk.unsupported module".

BTW, have you checked the case of jdk.unsupported?

and whether we call it "documented modules" or something else, vendor specific modules are, IMHO, out of scope with this switch.

We need to base the implementation on some clear definition which modules should be observable. And "documented modules" sure sounded like something that would be documented somewhere ;-P

I think that "documented modules" is basically this

# Modules that should be visible for 9 - the documented modules:
CT_MODULES := $(DOCS_MODULES)

That doesn't explain which modules are "documented".

The names flow into the processing and eventually to ct.sym.

Now I see where you are coming from. In this particular scenario ct.sym is only used to get the list of "documented modules".

To me this still feels odd, because ct.sym itself is deliberately undocumented. But perhaps it's the best we get on this matter ... BUT where, to begin with, did you find documentation of something called system-modules inside ct.sym? Actually, I do not see such a file in JDK > 21 !!

@wilx

wilx commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

It is all searching, looking at the JDK source code, guessing, and AI, of course. They changed the contents of the ct.sym after 21 and removed the system-modules and added current-release .sig and module-info.sig entries instead. That's why the code falls back to ct.sym signatures when it is missing.

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.

2 participants