Java "IllegalAccessError" (JPMS module) in CI - Fix Module Access
IllegalAccessError at runtime usually means the module system (or a binary mismatch) blocked access to a type that compiled fine. A package is not exported/opened by the module that owns it, or two incompatible versions of a class are present.
What this error means
A run or test throws java.lang.IllegalAccessError: class A (in module m) cannot access class B (in module n) because module n does not export the package to module m.
java.lang.IllegalAccessError: class com.example.app.Main (in module app)
cannot access class com.example.internal.Engine (in module core) because
module core does not export com.example.internal to module appCommon causes
The package is not exported/opened to the caller
Under JPMS a package is encapsulated unless exports/opens lists it. Reflective or direct access from another module is rejected with IllegalAccessError.
Split package or duplicate class versions
The same package supplied by two modules/jars, or two versions of a class, can also surface as IllegalAccessError when the loader links the wrong one.
How to fix it
Export or open the package in module-info
Declare the access the consumer needs in the owning module.
module core {
exports com.example.api; // compile + runtime access
opens com.example.internal to app; // reflective access only
}Open at launch when you cannot edit the module
Pass --add-exports / --add-opens to the test or run JVM as a stopgap.
- run: >
java
--add-opens core/com.example.internal=app
-jar app.jarHow to prevent it
- Design module boundaries with explicit
exports/opens, avoid split packages, and keep one version of each library on the module path.