Summary
-------
Strongly encapsulate all internal elements of the JDK by default, except
for [critical internal APIs][crit] such as `sun.misc.Unsafe`. Allow end
users to choose the relaxed strong encapsulation that has been the
default since JDK 9.
[crit]: https://openjdk.java.net/jeps/260#Description
Problem
-------
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
non-`public` elements of `java.*` packages, and all elements of `sun.*`
and other internal packages, for packages that existed in JDK 8.
This arrangement is called [_relaxed strong encapsulation_][relax].
We released JDK 9 in September 2017. Most of the commonly-used
internal elements of the JDK now have [standard replacements][replace].
Developers have had over three years in which to migrate away from
internal elements of the JDK to standard APIs such as
`java.lang.invoke.MethodHandles.Lookup::defineClass`, `java.util.Base64`,
and `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 `sun.misc.Unsafe`.
[relax]: https://openjdk.java.net/jeps/261#Relaxed-strong-encapsulation
[replace]: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool#JavaDependencyAnalysisTool-ReplaceusesoftheJDK'sinternalAPIs
Solution
--------
- Change the default mode of the `--illegal-access` option from
`permit` to `deny`. With this change, packages that existed in
JDK 8 and do not contain [critical internal APIs][crit] will no
longer be open by default; a complete list is available
[here][jdk8-pkgs]. The `sun.misc` package will still be exported by
the `jdk.unsupported` module, and will still be accessible via
reflection.
- Deprecate the `--illegal-access` option 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][se9-relax]
to disallow the opening of any package by default in any Java
Platform Implementation, unless that package is explicitly declared
to be `open` in the declaration of its containing module.
- No change to `javac` is 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](https://openjdk.java.net/jeps/396).
[se9-relax]: https://cr.openjdk.java.net/~iris/se/9/java-se-9-fr-spec-01/#Relaxing-strong-encapsulation
[jdk8-pkgs]: https://bugs.openjdk.java.net/secure/attachment/91418/jdk8-packages-encapsulated-by-default.txt
Specification
-------------
### Man page for the `java` launcher
@@ -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][se9-relax] 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>
[se9-relax]: https://cr.openjdk.java.net/~iris/se/9/java-se-9-fr-spec-01/#Relaxing-strong-encapsulation