JDK-8266852 : CSR for JEP 403: Strongly Encapsulate JDK Internals
  • Type: CSR
  • Component: core-libs
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 17
  • Submitted: 2021-05-10
  • Updated: 2021-05-13
  • Resolved: 2021-05-13
Related Reports
CSR :  
Description
Summary
-------

Strongly encapsulate all internal elements of the JDK, except for
[critical internal APIs][crit] such as `sun.misc.Unsafe`.  It will no
longer be possible to relax the strong encapsulation of internal elements
via a single command-line option, as was possible in JDK 9 through JDK
16.

[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 JDK 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`.

In JDK 16 we transitioned the JDK from a default of relaxed strong
encapsulation to a default of strong encapsulation, while allowing users
to return to the relaxed posture if they wished.

We are now ready to take one more step toward strongly encapsulating all
internal elements of the JDK by removing the ability to choose relaxed
strong encapsulation.  This means that all internal elements of the JDK
will be strongly encapsulated 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 treatment of the `--illegal-access` option to issue a
    warning message stating that the option is ignored, and then ignore
    the option.

  - Revise the [related text in the Java Platform Specification][se16-relax]
    to forbid a global option to enable relaxed strong encapsulation.

With this change, it will no longer be possible for end users to use the
`--illegal-access` option to enable access to packages that existed in
JDK 8 and do not contain [critical internal APIs][crit]; a complete
list is available [here][jdk8-pkgs] (also see attachment).  **The `sun.misc` package will still
be exported by the `jdk.unsupported` module, and will still be accessible
via reflection.**

It will still be possible to use the [--add-opens][add-opens]
command-line option, or the [Add-Opens][modjar] JAR-file manifest
attribute, to open specific packages.

A detailed discussion of this change and its likely impact can be found
in [JEP 403](https://openjdk.java.net/jeps/403).

[se16-relax]: https://cr.openjdk.java.net/~iris/se/16/spec/fr/java-se-16-fr-spec/#Relaxing-strong-encapsulation
[jdk8-pkgs]: https://bugs.openjdk.java.net/secure/attachment/94609/jdk8-packages-strongly-encapsulated
[add-opens]: https://openjdk.java.net/jeps/261#Breaking-encapsulation
[modjar]: https://openjdk.java.net/jeps/261#Packaging:-Modular-JAR-files


Specification
-------------

### Man page for the `java` launcher

    --- a/closed/src/java.base/share/man/java.md
    +++ b/closed/src/java.base/share/man/java.md
    @@ -2697,65 +2697,14 @@ Java HotSpot VM.

     ## Deprecated Java Options

     These `java` options are deprecated and might be removed in a future JDK
     release. They're still accepted and acted upon, but a warning is issued when
     they're used.

    -`--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.
    -
    -    -   `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.
    -
    -    -   `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 is the default.
    -
    -    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.
    -
    -    -   If the component still needs to be fixed, then you can contact its
    -        maintainers and ask them to replace their use of JDK-internal APIs with
    -        the proper exported APIs.
    -
    -    If you must continue to use a component that requires illegal access, then
    -    you can eliminate the warning messages by using one or more `--add-opens`
    -    options to open only those internal packages to which access is required.
    -
    -    To verify that your application is ready for a future version of the JDK,
    -    run it with `--illegal-access=deny` along with any necessary `--add-opens`
    -    options. Any remaining illegal-access errors will most likely be due to
    -    static references from compiled code to JDK-internal APIs. You can identify
    -    those by running the [jdeps](jdeps.html) tool with the `--jdk-internals`
    -    option. For performance reasons, the current JDK does not issue warnings
    -    for illegal static-access operations.
    -
     `-Xfuture`
     :   Enables strict class-file format checks that enforce close conformance to
         the class-file format specification. Developers should use this flag when
         developing new code. Stricter checks may become the default in future
         releases.

     `-Xloggc:`*filename*
    @@ -2810,16 +2759,20 @@ they're used.
         By default, this option is disabled.

     ## Obsolete Java Options

     These `java` options are still accepted but ignored, and a warning is issued
     when they're used.

    -None in JDK 17.
    -
    +`--illegal-access=`*parameter*
    +:   Controlled _relaxed strong encapsulation_, as defined in [JEP
    +    261](https://openjdk.java.net/jeps/261#Relaxed-strong-encapsulation).
    +    This option was deprecated in JDK 16 by [JEP
    +    396](https://openjdk.java.net/jeps/396) and made obsolete in JDK 17
    +    by [JEP 403](https://openjdk.java.net/jeps/403).

     ## Removed Java Options

     These `java` options have been removed in JDK 17 and using them results in an
     error of:

     >   `Unrecognized VM option` *option-name*

### Java SE Platform Specification

The following text will replace the
[���Relaxing strong encapsulation��� subsection][se16-relax] of the Platform
Specification:


    <p><title>Relaxing strong encapsulation</title> As an aid to migration,
    previous versions of this Specification permitted an Implementation to
    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.  This is no longer permitted.

    <p> (The Reference Implementation provided this capability via the
    command-line option <code>--illegal-access=permit</code>.) </p>

    <p> An Implementation must not relax the strong encapsulation of any of its
    modules, either by default or upon request.  That is, its run-time system
    must not behave as if some 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>

Comments
Moving to Approved.
13-05-2021

Moving to Provisional. Before the request is Finalized, please include the list of critical internal APIs directly in this request (either the specification section or as an attachment) rather than citing an external webpage.
11-05-2021