Fix Version/s: 16
Compatibility Kind:binary, behavioral
Compatibility Risk Description:
Interface Kind:add/remove/modify command line option
Strongly encapsulate all internal elements of the JDK by default, except
for critical internal APIs such as
sun.misc.Unsafe. Allow end
users to choose the relaxed strong encapsulation that has been the
default since JDK 9.
Over the years the developers of various libraries, frameworks, tools, and applications have used internal elements of the JDK in ways that compromise both security and maintainability.
In Java 9, we improved both the security and the maintainability of
the JDK by strongly encapsulating all new internal elements, thereby
limiting access to them. As an aid to migration, however, we
deliberately chose not to strongly encapsulate, at run time, the content
of packages that existed in JDK 8. Library and application code on
the class path could thus continue to use reflection to access the
public elements of
java.* packages, and all elements of
and other internal packages, for packages that existed in JDK 8.
This arrangement is called relaxed strong encapsulation.
We released JDK 9 in September 2017. Most of the commonly-used
internal elements of the JDK now have standard replacements.
Developers have had over three years in which to migrate away from
internal elements of the JDK to standard APIs such as
java.lang.ref.Cleaner. Many library, framework, and tool
maintainers have completed that migration and released updated versions
of their components. We are now ready to take the next step toward the
strong encapsulation of all internal elements of the JDK — except for
critical internal APIs such as
Change the default mode of the
deny. With this change, packages that existed in JDK 8 and do not contain critical internal APIs will no longer be open by default; a complete list is available here. The
sun.miscpackage will still be exported by the
jdk.unsupportedmodule, and will still be accessible via reflection.
--illegal-accessoption for removal in a future release, and arrange for a deprecation warning to be issued when it is used.
Revise the related text in the Java Platform Specification to disallow the opening of any package by default in any Java Platform Implementation, unless that package is explicitly declared to be
openin the declaration of its containing module.
No change to
javacis needed, since internal elements of the JDK have been strongly encapsulated by default since JDK 9.
A detailed discussion of this change and its likely impact can be found in JEP 396.
Man page for the
@@ -814,38 +814,36 @@ the Java HotSpot Virtual Machine. `--illegal-access=`*parameter* : When present at run time, `--illegal-access=` takes a keyword *parameter* to specify a mode of operation: - > **Note:** This option will be removed in a future release. + > **Note:** This option is deprecated and will be removed in a future release. - `permit`: This mode opens each package in each module in the run-time image to code in all unnamed modules ( such as code on the class path), if that package existed in JDK 8. This enables both static access, (for example, by compiled bytecode, and deep reflective access) through the platform's various reflection APIs. The first reflective-access operation to any such package causes a warning to be issued. However, no warnings are issued after the first occurrence. This single warning - describes how to enable further warnings. This mode is the default for - the current JDK but will change in a future release. + describes how to enable further warnings. - `warn`: This mode is identical to `permit` except that a warning message is issued for each illegal reflective-access operation. - `debug`: This mode is identical to `warn` except that both a warning message and a stack trace are issued for each illegal reflective-access operation. - `deny`: This mode disables all illegal-access operations except for those enabled by other command-line options, such as `--add-opens`. - This mode will become the default in a future release. + This mode is the default. - The default mode, `--illegal-access=permit`, is intended to make you aware - of code on the class path that reflectively accesses any JDK-internal APIs - at least once. To learn about all such accesses, you can use the `warn` or - the `debug` modes. For each library or framework on the class path that - requires illegal access, you have two options: + If your application does not work with the default mode of + `--illegal-access=deny` then you can learn more about what is going + on with the `warn` and `debug` modes. For each library or framework + on the class path that requires illegal access, you have two options: - If the component's maintainers have already released a fixed version that no longer uses JDK-internal APIs then you can consider upgrading to that version.
“Relaxing strong encapsulation” subsection of the Java SE Platform Specification
Rather than incorporate the text of this section from the Java SE 9 Platform Specification by reference, the new Platform Specification will instead include this text:
<p><title>Relaxing strong encapsulation</title> As an aid to migration, an Implementation may provide a means to invoke its run-time system with one or more packages of one or more of its modules open to code in all unnamed modules, &ie;, to code on the class path. If the run-time system is invoked in this way, and if by doing so some invocations of the reflection APIs succeed where otherwise they would have failed, then the first such invocation must cause a warning to be issued on the standard error stream. Later such invocations may also cause warnings to be issued. </p> <p> (The Reference Implementation provides this capability via the command-line option <code>--illegal-access=permit</code>.) </p> <p> An Implementation must not, by default, relax the strong encapsulation of any of its modules. That is, its run-time system must not customarily behave as if various packages in the Implementation's modules are open when they are not open according to their module declarations. A package, or an entire module, is open to code in all unnamed modules if and only if: </p> <ul> <li> It is explicitly declared to be open, without qualification, in a module declaration, or </li> <li> The run-time system is explicitly invoked to open it to code in all unnamed modules, <a href="#Overriding-module-declarations">as provided for below</a>. </li> </ul> <p> A future revision of this Specification is expected to disallow relaxed strong encapsulation entirely. </p>