Java "package X is declared in module Y, which does not export it" - Fix in CI
JPMS strongly encapsulates packages: a module only exposes packages it explicitly exports. Your code uses a type from a package the owning module keeps internal, so it is invisible even though the module is read.
What this error means
javac fails with package com.example.internal is declared in module com.example.lib, which does not export it to module com.example.app. The class exists but the package is not exported to you.
error: package com.example.internal is declared in module com.example.lib,
which does not export it to module com.example.app
import com.example.internal.Helper;
^Common causes
Using an unexported (internal) package
You depend on a package the library deliberately keeps internal; JPMS forbids access from outside.
Reflection into a non-open package
A framework reflects into a package that is exported but not opens, so deep reflective access is denied.
Missing a qualified export
In a multi-module repo you own, the producing module exports the package only to specific modules and not to the consumer.
How to fix it
Export the package (if you own the module)
Add an exports directive to the producing module.
module com.example.lib {
exports com.example.internal; // or: exports ... to com.example.app;
}Open the package for reflection
If a framework needs deep reflection, open rather than export.
module com.example.lib {
opens com.example.model to com.fasterxml.jackson.databind;
}Break encapsulation at launch as a last resort
For third-party internals you cannot change, add the flag explicitly (and treat as debt).
java --add-exports com.example.lib/com.example.internal=ALL-UNNAMED -jar app.jarHow to prevent it
- Depend only on exported, public packages of other modules.
- Use
opens ... tofor frameworks that need reflective access. - Avoid
--add-exports/--add-opensfor code you can refactor to the public API.