All JDK Release Notes
               JDK 9 Release Notes

JDK 9 Release Notes

Important Changes and Information



The following items describe important changes and information about this release. In some cases, the descriptions provide links to additional detailed information about an issue or a change. This page does not duplicate the descriptions provided by the other JDK 9 Release Notes pages and:

You should be aware of the content in those documents as well as the items described in this page.

The descriptions below also identify potential compatibility issues that you might encounter when migrating to JDK 9. See the JDK 9 Migration Guide for descriptions of specific compatibility issues.

The Kinds of Compatibility page on the OpenJDK wiki identifies three types of potential compatibility issues for Java programs used in these descriptions:

  • Source: Source compatibility concerns translating Java source code into class files.

  • Binary: Binary compatibility is defined in The Java Language Specification as preserving the ability to link without error.

  • Behavioral: Behavioral compatibility includes the semantics of the code that is executed at runtime.

See the Compatibility & Specification Review (CSR) page on the OpenJDK wiki for more information about compatibility as it relates to JDK 9.


 

core-libs
 Module System

 

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

 

core-libs
 New JDK Versioning Scheme 

JDK 9 uses a new version string format. The most notable changes are the removal of the “1.” from the beginning of the version string and the use of 3 or more separate elements to specify major, minor, and security updates. All code that parses the value of the system properties java.version, java.specification.version, or java.vm.specification.version should be examined to ensure that it works with the new scheme. Maintainers of code that parses these properties should also be aware of the new Runtime.version() API.

Details for the new version string format can be found in JEP 223: New Version-String Scheme.

 

core-libs/java.util:i18n
 Use CLDR locale data by default 

In JDK 9, the default locale data uses data derived from the Unicode Consortium's Common Locale Data Repository (CLDR). As a result, users may see differences in locale sensitive services behavior and/or translations. For example, CLDR does not provide localized display names for most 3-letter time zone IDs, thus the display names may be different from JDK 8 and older. The JDK continues to ship with the legacy JRE locale data and the system property java.locale.providers can be used to configure the lookup order. To enable behavior compatible with JDK 8, the system property can be set with:

-Djava.locale.providers=COMPAT,SPI

For more detail, refer to the JEP 252.

 

hotspot/gc
 Change default GC to G1 

In JDK 9, the default garbage collector is G1 when a garbage collector is not explicitly specified. G1 provides a better overall experience for most users when compared to a throughput-oriented collector such as the Parallel GC, which was previously the default.

The options to configure the G1 collector are documented in the java command page (link). See also JEP 248 for more information on this change.

 

infrastructure
 Modular Run-Time Images 

The JDK and JRE run-time images have been restructured as documented in JEP 220. The compatibility issues due to the changes are documented in the "Risks and Assumptions" section of the JEP and also summarized here.

  • Tools and libraries that rely on the existence of the jre directory, rt.jar, or tools.jar may need to be updated to work with the new layout and/or may need to be updated to use the jrt file system provider to access class files and other resources in the runtime image.

  • All user-editable configuration files are now located in the JDK/JRE conf directory. This includes the security policy file and other properties files. Scripts or procedures that rely on the old location of these files may need to be updated.

  • On Linux and Solaris, libjvm.so is now located in the JDK/JRE lib directory (it was located in lib/$ARCH in previous releases). Applications that use the JNI invocation API to create the VM may need to be updated to locate libjvm.so in its new location.

  • src.zip has moved from the top-level directory to the lib directory and now includes both the JDK and JavaFX source files in module directories. IDEs or tools that open this zip file may need to be updated.

  • The deprecated Endorsed-Standards Override Mechanism has been removed in this release. The runtime will refuse to start if ${java.home}/lib/endorsed exists or the system property java.endorsed.dirs is specified on the command line. The javac compiler will only accept the -endorseddirs option when compiling to JDK 8 or older. Applications that rely on this mechanism should migrate to the upgradeable modules mechanism, documented in JEP 261.

  • The deprecated Extensions Mechanism has been removed. The runtime will refuse to start if ${java.home}/lib/ext exists or the system property java.ext.dirs is specified on the command line. The javac compiler will only accept the -extdirs option when compiling to JDK 8 or older. The rmic compiler will no longer accept the -extdirs options. Applications that rely on this mechanism should consider deploying the libraries on the class path or as modules on the module path.

 

tools/javac
 Update class file version to 53.0 

When generating class files in conjunction with -target 9 (specified either explicitly or implicitly), javac will generate class files with a major version number of 53. For details of version 53 class files, see the Java Virtual Machine Specification.

The JDK classes themselves mostly use version 53 class files.

Tools or libraries that rely on ASM or other bytecode manipulation libraries may need updated versions of these libraries to work with version 53 class files.

 

tools/javac
 Remove support for 1.5 and earlier source and target options 

The javac command no longer supports -source or-target values for releases before 6/1.6. However, older class files are still readable by javac. Source code for an older release can be ported to a newer source level. To generate class files usable by releases older than JDK 6, a javac from a JDK 6, 7, or 8 release family can be used.

JEP 182 documents the policy for retiring old -source and -target options.