Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8266852

CSR for JEP 403: Strongly Encapsulate JDK Internals

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 17
    • Component/s: core-libs
    • Labels:
      None
    • Compatibility Kind:
      binary, behavioral
    • Compatibility Risk:
      medium
    • Compatibility Risk Description:
      Hide
      Existing Java applications that depend upon the `--illegal-access` option
      to enable relaxed strong encapsulation will no longer run. In place of
      `--illegal-access` it will still be possible to use the `--add-opens`
      command-line option, or the `Add-Opens` JAR-file manifest attribute, to
      open specific packages.
      Show
      Existing Java applications that depend upon the `--illegal-access` option to enable relaxed strong encapsulation will no longer run. In place of `--illegal-access` it will still be possible to use the `--add-opens` command-line option, or the `Add-Opens` JAR-file manifest attribute, to open specific packages.
    • Interface Kind:
      add/remove/modify command line option
    • Scope:
      SE

      Description

      Summary

      Strongly encapsulate all internal elements of the JDK, except for critical internal APIs 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.

      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.

      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.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.

      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 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; a complete list is available here (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 command-line option, or the Add-Opens JAR-file manifest attribute, to open specific packages.

      A detailed discussion of this change and its likely impact can be found in JEP 403.

      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 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>

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              mr Mark Reinhold
              Reporter:
              mr Mark Reinhold
              Reviewed By:
              Alan Bateman, Alex Buckley, Brian Goetz, Iris Clark, Mandy Chung
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: