JDK 9: Proposal to allow illegal reflective access by default
© Shutterstock / Yeexin Richelle
Mark Reinhold, Chief Architect of the Java Platform Group at Oracle, came up with the proposal to allow illegal reflective access from code on the class path by default in JDK 9 and to disallow it in a future release. Although the idea was well received, he emphasized that the change won’t “magically solve every JDK 9 adoption problem.”
Mark Reinhold has a new proposal for JDK 9: to allow illegal reflective access from code on the class path by default in JDK 9 and to disallow it in a future release. He wrote in a message to the OpenJDK mailing list that “the strong encapsulation of JDK-internal APIs has triggered many worried expressions of concern that code that works on JDK 8 today will not work on JDK 9 tomorrow, yet no advance warning of this change was given in JDK 8.”
To help the ecosystem “migrate to the modular Java platform at a more relaxed pace,” Reinhold proposed to allow illegal reflective access from code on the class path by default in JDK 9 and to disallow it in a future release.
What does that mean exactly?
The Chief Architect of the Java Platform Group at Oracle explained that the existing “big kill switch” of the `–permit-illegal-access` option will become the default behavior of the JDK 9 run-time system but emphasized that there won’t be as many warnings. He also added that the current behavior of JDK 9 [where illegal reflective-access operations from code on the class path are not permitted] will become the default in a future release and nothing will change at compile time.
Reinhold wrote that the recently-introduced `–permit-illegal-access` option will be replaced by a more general option, `–illegal-access`.
This option will take a single keyword parameter, as follows:
This will be the default mode for JDK 9. It opens every package in every explicit module to code in all unnamed modules, i.e., code on the class path, just as `–permit-illegal-access` does today.
The first illegal reflective-access operation causes a warning to be issued, as with `–permit-illegal-access`, but no warnings are issued after that point. This single warning will describe how to enable further warnings.
This causes a warning message to be issued for each illegal reflective-access operation. This is equivalent to the current `–permit-illegal-access` option.
This causes both a warning message and a stack trace to be shown for each illegal reflective-access operation. This is equivalent to combining today’s `–permit-illegal-access` option with `-Dsun.reflect.debugModuleAccessChecks`.
This disables all illegal reflective-access operations except for those enabled by other command-line options, such as `–add-opens`. This will become the default mode in a future release.
Reinhold warned that “the proposed default mode enables the run-time system to issue a warning message, possibly at some time long after startup, without having been explicitly requested to do so. This may be a surprise in production environments since it’s extremely unusual for the run-time system to issue any warning messages at all. If the default mode permits illegal reflective access, however, then it’s essential to make that known so that people aren’t surprised when this is no longer the default mode in a future release.”
He added that warning messages in any mode can be avoided [just like before] by the judicious use of the `–add-exports` and `–add-opens` options.
If adopted, the proposal will require some changes to JEP 260, “Encapsulate Most Internal APIs”. Although APIs that are internal to the JDK will still be strongly encapsulated from the standpoint of code in modules [whether those modules are automatic or explicit] they won’t appear to be encapsulated at run time from the standpoint of code on the class path.
Furthermore, when `deny` becomes the default mode, Reinhold expects `permit` to remain supported for at least one release, so that developers can continue to migrate their code. It’s worth mentioning that the `permit`, `warn`, and `debug` modes will, over time, be removed, and the same thing will happen to the `–illegal-access` option.
Probably the most important thing to grasp is that even if the proposal is adopted and the change takes effect, it won’t “magically solve every JDK 9 adoption problem.The concrete types of the built-in class loaders are still different, `rt.jar` is still gone, the layout of a system image is still not the same and the version string still has a new format.”
Cédric Champeau, Core Developer at Gradle, Inc. opined that the proposal is “very reasonable” while Michael Nascimento agreed that the compromise is “well-thought“. The latter added that “real world applications need this and it’s a very welcome move.”
Nicolai Parlog, the author of CodeFX, opined that a “quiet” argument would be “helpful” but claimed that “making the lenient option the default is a bad decision, needlessly prolonging a proper clean-up of the ecosystem without any
Java’s stewards have been warning against using internal APIs for 20 years. Jigsaw announced to make them inaccessible for nigh two years now. Java 8 will be supported until at least July 2018 and even after that all that is needed to get around this specific Java 9 compatibility problem is to add `–permit-illegal-access`.
All that is not enough, though? Even adding that single flag is too hard? If spending an hour or two reading up on JPMS and then adding that flag is too much to ask, then how can one expect the same people to clean up their code?
With illegal access being permitted by default much fewer developers will be aware of the problem and much less pressure will be put on library and framework maintainers as well as on project management to invest into paying back this particular form of technical debt. So we get much less momentum to make the necessary changes in exchange for… not having to add a flag? That’s ridiculous, an Armutszeugnis for the Java community!
Hazelcast’s Christoph Engelbert also appreciated a fully ‘quiet’ mode for their customers and added that making it the default for Java 9 “sounds meaningful.”
Meanwhile, Uwe Schindler, a committer and PMC member of Apache Lucene and Solr, opined that Reinhold’s proposal is a “disaster since buggy software may use the big kill switch.”