Java › Java Platform Module System (JPMS)
How does JPMS's strong encapsulation interact with reflection-heavy frameworks and libraries that predate the module system, and what specific JVM flags (like --add-opens) exist as an escape hatch for cases where proper module declarations aren't feasible?
AdvancedAnswer
For legacy libraries or frameworks that can't be modified to add proper opens directives (perhaps a third-party dependency you don't control, or code you can't immediately update), the --add-opens (and similarly --add-exports, --add-reads) command-line flags let you grant the necessary access externally, at application launch time, without modifying the target module's own module-info.java -- this serves as an important practical escape hatch during migration or when depending on not-yet-modularized libraries, though it's generally considered a temporary workaround rather than a permanent solution, since it requires the exact access grant to be specified explicitly at every launch (easy to forget or misconfigure) rather than being a permanent, self-documenting part of the module's own declared contract.
# Grant a specific external module deep reflective access to an internal package
# WITHOUT modifying that module's own module-info.java
java --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens com.example.mymodule/com.example.mymodule.internal=com.thirdparty.framework \
--module com.example.myapp
# Commonly needed historically for older versions of reflection-heavy frameworks
# (like some Spring/Hibernate versions) accessing JDK internals not originally exported for this purposeReal-world example A team upgrading to a newer JDK version discovers a legacy dependency library throws InaccessibleObjectException due to JPMS's stricter default encapsulation, temporarily resolving the immediate blocker with an explicit --add-opens flag while separately tracking updating to a newer, properly JPMS-compatible version of that library as the genuine long-term fix rather than relying on the flag indefinitely.