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

CSR for JEP 396: Strongly Encapsulate JDK Internals by Default

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 16
    • core-libs
    • None
    • binary, behavioral
    • medium
    • Hide
      Existing Java code that depends upon internal elements of the JDK, other than critical internal APIs such as sun.misc.Unsafe, will no longer run.
      Show
      Existing Java code that depends upon internal elements of the JDK, other than critical internal APIs such as sun.misc.Unsafe, will no longer run.
    • add/remove/modify command line option
    • SE

      Summary

      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.

      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.

      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.

      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 will no longer be open by default; a complete list is available here. 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 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.

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

            mr Mark Reinhold
            mr Mark Reinhold
            Alan Bateman, Alex Buckley, Iris Clark, Mandy Chung (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: