Details

    • Verification:
      Verified

      Description

      Java SE and the JDK have been significantly updated by the introduction of the Java Platform Module System (JSR 376) and using the module system to modularize the Java SE Platform and the JDK. The compatibility issues due to the changes are documented in the "Risks and Assumptions" section of [JEP 261](http://openjdk.java.net/jeps/261) and also summarized here.

      - All JDK internal classes are now encapsulated at compile-time. Using `javac` to compile source code with references to JDK internal classes will now fail. This differs to previous releases where `javac` emitted warnings of the form "XXX is an internal proprietary API and may be removed in a future release". JEP 261 documents the `--add-exports` option which may be used as a temporary workaround to compile source code with references to JDK internal classes.

      - All JDK internal classes are also encapsulated at run-time but most remain accessible to applications and libraries on the class path. Specifically, all public classes in JDK internal packages that existed in JDK 8 remain accessible to code on the class path. Furthermore, these JDK internal packages, and the standard packages in Java SE 8, are open in JDK 9 for so-called _deep reflection_ by code on the class path. This allows existing code on the class path that relies on the use of `setAccessible` to break into JDK internals, or to do other illegal access on members of classes in these packages, to work as per previous releases. A future JDK release will change this policy so that these packages will not be open and illegal access to members of classes in these packages will be denied. To help identify code that needs to be fixed, the JDK emits a warning to standard error on the first use of core reflection that performs an illegal access. The warning is not suppressible.

        Developers of applications that observe "illegal access" warnings caused by code in libraries that they use are encouraged to submit bugs to the library maintainers.

        Developers of libraries using core reflection that may rely on illegal access are encouraged to test with `--illegal-access=warn` or `--illegal-access=debug` to identify code in their library that may need updating.

        All developers are encouraged to use the `jdeps` tool to identify any static references to JDK internal classes. The `jdeps` tool was introduced in JDK 8 and has many significant improvements in JDK 9.

        In preparation for a JDK release that denies illegal access, applications and libraries should be tested with `--illegal-access=deny`. As documented in JEP 261, running with `-Dsun.reflect.debugModuleAccessChecks=access` may help to locate code that silently ignores `IllegalAccessException` or `InaccessibleObjectException`.

      - As detailed in JEP 261, the default set of root modules for applications on the class path is the `java.se` module rather than the `java.se.ee` module. Applications and libraries that make use of classes in module `java.xml.bind` (JAXB), module `java.xml.ws` (JAX-WS), module `java.corba` (CORBA), or other modules shared between Java SE and Java EE may need changes to how they are compiled and deployed. Furthermore, these modules have been deprecated in Java SE 9 for removal in a future release so applications and libraries using these APIs will need to eventually migrate to using the standalone releases of these modules. The JDK 9 Migration Guide details the options for applications and libraries using these APIs.

      - As documented in JEP 261, if a package is defined in both a named module and on the class path then the package on the class path will be ignored. This may impact applications that have (perhaps unknowingly) added classes to Java SE or JDK packages by means of the class path.

      - The boot class path has been mostly removed in this release. The `java -Xbootclasspath` and `-Xbootclasspath/p` options have been removed. The `javac -bootclaspath` option can only be used when compiling to JDK 8 or older. The system property `sun.boot.class.path` has been removed. Deployments that rely on overriding platform classes for testing purposes with `-Xbootclasspath/p` will need to changed to use the `--patch-module` option that is documented in JEP 261. The `-Xbootclasspath/a` option is unchanged.

      - The application class loader is no longer an instance of `java.net.URLClassLoader` (an implementation detail that was never specified in previous releases). Code that assumes that `ClassLoader::getSytemClassLoader` returns a `URLClassLoader` object will need to be updated. Note that Java SE and the JDK do not provide an API for applications or libraries to dynamically augment the class path at run-time.

      - The classes in many non-core modules are now defined to the platform class loader rather than the boot class loader. This may impact code that creates class loaders with `null` as the parent class loader and assumes that all platform classes are visible to the parent class loader. Such code may need to be changed to use the platform class loader as the parent class loader (see `java.lang.ClassLoader::getPlatformClassLoader`). Tool agents that add supporting classes to the boot class path may also assume that all platform classes are visible to the boot class loader. The `java.lang.instrument` package description provides more information on this topic for maintainers of java agents.

      - The `java.lang.Package` API has been updated to represent a run-time package.
      The `Class::getPackage` method returns a `Package` object whose name is an empty
      string for a class in the unnamed package. This may impact code that expects
      `Class::getPackage` to return null for a class in the unnamed package.
      In addition, `Package::getPackages` and `ClassLoader::getPackages` may return
      an array with more than one `Package` object of the same package name, each
      defined by a different class loader in the class loader hierarchy. This differs to
      previous releases that only one `Package` object of a package name will be included
      in the returned array.

      - The `java.lang.Package` objects created by the built-in class loaders for packages in named modules do not have specification or implementation versioning information. This differs to previous releases where specification and implementation versioning information was read from the main manifest of `rt.jar`. This change may impact code that invokes `getPackage` on a platform class and expects the `Package::getSpecificationXXX` or `Package::getImplementationXXX` methods to return non-null values.

      - The `Class::getResource` and `Class::getResourceAsStream` methods have been updated in Java SE 9 so that invoking them on a Class in a named module will only locate the resource in the module. This may impact code that invokes these methods on platform classes on the assumption that the class path will be searched. Code that needs to search the class path for a resource should be changed to use `ClassLoader::getSystemResource` or `ClassLoader::getSystemResourceAsStream`.

      - JDK internal resources, other than class files, in the standard and JDK modules can no longer be located with the `ClassLoader::getResourceXXX` APIs. This may impact code that relies on using these APIs to get at JDK internal properties files or other resources. The `Class::getResourceXXX` APIs will continue to locate JDK internal resources in packages that are open for illegal access (see above). A further change to these APIs is that the permission needed, when running with a security manager, to locate resources in the run-time image has changed. The permission needed to locate resources in modules in the run-time image is `RuntimePermission("accessSystemModules")` and so different to previous releases where permission to read `${java.home}/lib/rt.jar` was needed.

      - Stack traces have been updated to include module names in the stack trace elements for classes in named modules. Code that parses stack traces may need to be updated.

      - The JDK may not start (meaning `java -version` fails) in some unsupported configurations. In particular, if the system property `file.encoding` is set on the command line with the name of a charset that is not in the `java.base` module then startup will fail with an error message to indicate that the charset is not supported.

      - In previous releases, the "double equals" syntax could be used when setting the security policy to override the JDK security policy file (e.g. `-Djava.security.policy==appserver.policy`). This has changed in JDK 9 so that it augments the permissions granted to the standard and JDK modules. This change means that application servers that override the JDK policy file do not need to copy the permissions granted to standard and JDK modules. More details on this issue can be found in JDK-8159752.

      - Maintainers of JVM TI agents to instrument or profile code that executes early in VM startup should review the changes in JEP 261 and the changes in the JVM TI specification. The default behavior has changed so that the `ClassFileLoadHook` event is not sent during the primordial phase, and the `VMStart` event (to signal the beginning of the start phase) is delayed until the module system is initialized. The JVM TI specification has been updated to define new capabilities for agents that need events for code that is executed before the VM is fully initialized.

      Source Compatibility Issues
      -------------------------------------
      - Java SE 9 adds the `Module` class to the `java.lang` package which is implicitly imported on demand (i.e., `import java.lang.*`). If code in an existing source file imports some other package on demand, and that package declares a `Module` type, and the existing code refers to that type, then the source file will not compile without changing it to use a single-type-import declaration (i.e., `import otherlib.Module`).

      - Java SE 9 adds two abstract methods to `java.lang.instrument.Instrumentation`. This interface isn't intended to be implemented outside of the `java.instrument` module but if there are implementations they will not compile with JDK 9 until they are updated to implement the new methods added in Java SE 9.

      - Java SE 9 adds a six-parameter `transform` method to `java.lang.instrument.ClassFileTransformer` as a default method. This means that `ClassFileTransformer` is no longer a functional interface (JLS 9.8). Existing source code that uses the pre-existing five-parameter transform method as a functional interface will no longer compile.

        Attachments

          Activity

            People

            Assignee:
            alanb Alan Bateman
            Reporter:
            alanb Alan Bateman
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: