← Recipes

Module Access Workaround

Bridge reflective library access while migrating to Java's strong encapsulation model.

Flags

--add-opens--add-exports

--add-opens opens a package for deep reflection. --add-exports exports a package for compile-time or runtime access. Both should be treated as explicit migration bridges, not broad tuning flags.

Option details

--add-opens java.base/java.lang=ALL-UNNAMED
Allows unnamed classpath code to use deep reflection on java.lang. This is commonly needed by older frameworks or agents that access private JDK internals.
--add-exports java.base/sun.nio.ch=ALL-UNNAMED
Exports an internal package so classpath code can access its public types. This is narrower than opening for deep reflection, but it still couples the application to JDK internals.

When to use it

Use this when a framework, agent, serializer, or legacy library still needs access to an internal JDK package and upgrading the dependency is not immediately possible.

Prefer a library upgrade over accumulating module opens. Each option documents a compatibility debt.

Java version support

--add-opens and --add-exports are module-system options introduced with Java 9. They are most often used when moving Java 8-era libraries onto Java 9+ strong encapsulation, especially Java 16 and Java 17+.

Related JEPs

Examples

java --add-opens java.base/java.lang=ALL-UNNAMED \
  -jar legacy-app.jar

Use this only for the package reported by the reflective-access failure.

java --add-exports java.base/sun.nio.ch=ALL-UNNAMED \
  -jar legacy-app.jar

Use this when code directly links to an internal exported type.

Verify

Search startup logs for illegal-access or reflective-access failures and remove the option after the dependency is fixed.