Java "module ... does not open ... InaccessibleObjectException" - Fix --add-opens
On JDK 17+ the JPMS module system strongly encapsulates internal JDK packages. Code (or a library, or a test framework) that uses deep reflection into java.base/java.lang now throws InaccessibleObjectException unless the run explicitly opens that package with --add-opens.
What this error means
A test or app fails with Unable to make ... accessible: module java.base does not "opens java.lang" to unnamed module (an InaccessibleObjectException). The same code ran on JDK 8/11 where illegal reflective access was merely warned about.
java.lang.reflect.InaccessibleObjectException: Unable to make field private
final java.util.Comparator java.util.TreeMap.comparator accessible: module
java.base does not "opens java.util" to unnamed module @1b6d3586Common causes
Deep reflection into an encapsulated JDK package
A mocking/serialization/proxy library reflects into internal JDK classes. JDK 16 made illegal reflective access an error, so on 17+ it throws instead of warning.
Run not granted the needed --add-opens
The fix is per-run JVM flags. If the test JVM or the app launch does not pass --add-opens for the package being reflected on, access is denied.
How to fix it
Open the package to the test JVM
Pass --add-opens to the forked test JVM (Surefire argLine / Gradle jvmArgs).
<!-- Maven Surefire -->
<configuration>
<argLine>--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED</argLine>
</configuration>Open at runtime for the application launch
For the app itself, pass the flags on the java command (or bake them into the manifest/JAVA_TOOL_OPTIONS).
java --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.util=ALL-UNNAMED \
-jar app.jarHow to prevent it
- Upgrade libraries to JDK-17-compatible versions that avoid deep reflection.
- Add the required
--add-opensto the test JVM args and the app launch. - Test on the target JDK so encapsulation errors surface before release.