Fix JDK 25 IllegalAccessError from module split in JavaUnrestrictedClassLoader#6836
Merged
sambsnyd merged 3 commits intoopenrewrite:mainfrom Feb 28, 2026
Conversation
…assLoader When running via Maven plugin on JDK 25, the ClassRealm classloader establishes loader constraints that prevent defineClass for certain jdk.compiler classes. The existing LinkageError fallback (from openrewrite#6736) delegates to the parent, but this creates a module split: some classes end up in the unnamed module while others land in jdk.compiler. Since jdk.compiler does not export its internal packages to unnamed modules, cross-references between split classes fail with IllegalAccessError. Fix by dynamically adding a module export from the named module to the classloader's unnamed module when falling back to parent delegation. Uses sun.misc.Unsafe to obtain a trusted MethodHandles.Lookup that can invoke Module.implAddExports, bypassing the module system's caller check. All Module API access is done via reflection for Java 8 source compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Member
|
Thanks for the help here @mcebanupgrade ! Sam has wrestled with classloaders quite a bit more than I have, so I've tagged him for review. |
sambsnyd
reviewed
Feb 28, 2026
Member
sambsnyd
left a comment
There was a problem hiding this comment.
I would like to accept this but the author's lack of confidence gives me pause. Have you tested that this change resolves the issue beyond the provided test? Knowing that this has been validated by more than Claude's assumptions would give me more confidence.
Member
|
Reading this again I think it looks OK. Seems reasonable to me that this would solve the problem. |
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

We've encountered this issue with the latest version of the rewrite lib and plugin. I asked Claude Code to analyze, fix and confirm the fix locally and here's the result.
I fully admit that the proposed changes here are beyond my understanding. The details bellow, generated by Claude
Summary
IllegalAccessError: class com.sun.tools.javac.parser.JavaTokenizer (in unnamed module) cannot access class com.sun.tools.javac.parser.Tokens$Comment$CommentStyle (in module jdk.compiler)because Maven's ClassRealm establishes loader constraints that force somejdk.compilerclasses to fall back to parent delegation, creating a module splitLinkageErrorcatch from Fix JDK 25 LinkageError in JavaUnrestrictedClassLoader #6736 correctly falls back to the parent classloader, but the returned class ends up injdk.compilermodule while classes already loaded viadefineClassremain in the unnamed module — andjdk.compilerdoesn't export its internal packages to unnamed modulessun.misc.Unsafe→ trustedMethodHandles.Lookup→Module.implAddExports(all via reflection for Java 8 source compatibility)Test plan
./gradlew :rewrite-java:test --tests "org.openrewrite.java.JavaUnrestrictedClassLoaderTest"— 3 tests pass (export mechanism, unnamed module no-op, idempotency)./gradlew :rewrite-java-25:compatibilityTest --tests "org.openrewrite.java.tree.AnnotationTest"— no regressionsmvn clean -Popenrewrite rewrite:run -Drewrite.activeRecipes=org.openrewrite.java.migrate.UpgradeToJava25on a real project with JDK 25 — BUILD SUCCESS (previously failed with IllegalAccessError)🤖 Generated with Claude Code