Java Platform, Standard Edition

Oracle JDK Migration Guide

Release 11

E94894-02

November 2018

Getting Started

The purpose of this guide is to help you identify potential issues and give you suggestions on how to proceed as you migrate your existing Java application to the latest JDK release. The guide also highlights the significant changes and enhancements done to the latest release.

Significant Changes in JDK 11 Release

Before migrating your application to JDK 11, you should understand what the updates and changes are between it and the JDK 10 release. If you are migrating from JDK 8, you should also be familiar with the differences between JDK 8 and later releases that are described in Migrating From JDK 8 to Later JDK Releases.

The following are some of the significant changes in JDK 11:

Oracle no longer offers JRE and Server JRE downloads; consequently, Auto-Update is not available anymore.

java.xml.ws.annotation: The subset of the JSR-250 Common Annotations defined by Java SE to support web services

java.corba: CORBA

java.transaction: The subset of the Java Transaction API defined by Java SE to support CORBA Object Transaction Services

java.activation: JavaBeans Activation Framework

java.se.ee: Aggregator module for the six modules above

jdk.xml.ws: Tools for JAX-WS

jdk.xml.bind: Tools for JAXB

Existing code with references to classes in these APIs will not compile without changes to the build. Similarly, code on the class path with references to classes in these APIs will fail with NoDefClassFoundError or ClassNotFoundException unless changes are made in how the application is deployed.

Security Updates

TLS 1.3 is the latest iteration (August 2018) of the Transport Layer Security (TLS) protocol and is enabled by default in JDK 11. This version focuses not only on speed improvements, but also updates the overall security of the protocol by emphasizing modern cryptography practices, and disallows outdated or weak crypto algorithms. (For example, RSA key exchange and plain DSA signatures are no longer allowed.)

Several features were added to the TLS 1.3 protocol to improve backwards compatibility, but there are several issues of which you need to be aware of. For details, see JEP 332.

Removal of Security Certificates

The following root certificates have been removed from the truststore in JDK 11:

Products that use certificates that have been removed may no longer work. If these certificates are required, then you must configure and populate the cacerts with the missing certs. To add certs to the truststore, see keytool in Java Platform, Standard Edition Tools Reference guide.

Removed APIs, Tools, and Components

This section provides details about the APIs, tools, and components that were removed in JDK 11.

Removed APIs in JDK 11

The following APIs were removed in JDK 11. Many of these APIs were deprecated in previous releases and have been replaced by newer APIs. For information on the possible alternatives, see JDK 11 API Specification.

When you run your application, look for warnings from the JVM about obsolete VM options. If the VM fails to start, then look for Removed GC Options.

If your application starts successfully, look carefully at your tests and ensure that the behavior is the same as on the JDK version you have been using. For example, a few early adopters have noticed that their dates and currencies are formatted differently. See Use CLDR Locale Data by Default.

To make your code work on the latest JDK release, understand the new features and changes in each of the JDK release.

Even if your program appears to run successfully, you should complete the rest of the steps in this guide and review the list of issues.

Update Third-Party Libraries

For every tool and third-party library that you use, you may need to have an updated version that supports the latest JDK release.

Check the websites for your third-party libraries and your tool vendors for a version of each library or tool that’s designed to work on the latest JDK. If one exists, then download and install the new version.

If you use Maven or Gradle to build your application, then make sure to upgrade to a more recent version that supports the latest JDK version.

If you use an IDE to develop your applications, then it might help in migrating the existing code. The NetBeans, Eclipse, and IntelliJ IDEs all have versions available that include support for the latest JDK.

You can see the status of the testing of many Free Open Source Software (FOSS) projects with OpenJDK builds at Quality Outreach on the OpenJDK wiki.

Compile Your Application if Needed

Compiling your code with the latest JDK compiler will ease migration to future releases since the code may depend on APIs and features, which have been identified as problematic. However, it is not strictly necessary.

If you need to compile your code with JDK 11 compiler, then take note of the following:

If you use the underscore character ("_") as a one-character identifier in source code, then your code won’t compile in JDK 11. It generates a warning in JDK 8, and an error, starting from JDK 9.

As an example:

static Object _ = new Object();

This code generates the following error message from the compiler:

MyClass.java:2: error: as of release 9, '_' is a keyword, and may not be used as a legal identifier.

If you use the -source and -target options with javac, then check the values that you use.

The supported -source/-target values are 11 (the default), 10, 9, 8, 7, and 6 (6 is deprecated, and a warning is displayed when this value is used).

In JDK 8, -source and -target values of 1.5/5 and earlier were deprecated, and caused a warning. In JDK 9 and above, those values cause an error.

Critical internal JDK APIs such as sun.misc.Unsafe are still accessible in JDK 11, but most of the JDK’s internal APIs are not accessible at compile time. You may get compilation errors that indicate that your application or its libraries are dependent on internal APIs.

To identify the dependencies, run the Java Dependency Analysis tool. See Run jdeps on Your Code. If possible, update your code to use the supported replacement APIs.

You may use the --add-exports option as a temporary workaround to compile source code with references to JDK internal classes.

You may see more deprecation warnings than previously.

Run jdeps on Your Code

Run the jdeps tool on your application to see what packages and classes your applications and libraries depend on. If you use internal APIs, then jdeps may suggest replacements to help you to update your code.

To look for dependencies on internal JDK APIs, run jdeps with the -jdkinternals option. For example, if you run jdeps on a class that calls sun.misc.BASE64Encoder, you’ll see:

For jdeps syntax, see jdeps in the Java Platform, Standard Edition Tools Reference.

Keep in mind that jdeps is a static analysis tool, and static analysis of code might not provide a complete list of dependencies. If the code uses reflection to call an internal API, then jdeps doesn’t warn you.

Migrating From JDK 8 to Later JDK Releases

There were significant changes made between the JDK 8 and later JDK releases.

Every new Java SE release introduces some binary, source, and behavioral incompatibilities with previous releases. The modularization of the Java SE Platform that happened in JDK 9 brought many benefits, but also many changes. Code that uses only official Java SE Platform APIs and supported JDK-specific APIs should continue to work without change. Code that uses JDK-internal APIs should continue to run but should be migrated to use the supported APIs.

The following sections describe the changes in the JDK package and APIs that you should be aware of when migrating your JDK 8 applications to later JDK releases.

Look at the list of changes that you may encounter as you run your application.

When your application is running successfully on the latest version of JDK, review Next Steps, which will help you avoid problems with future releases.

Understanding Runtime Access Warnings

Some tools and libraries use reflection to access parts of the JDK that are meant for internal use only. This illegal reflective access will be disabled in a future release of the JDK. Currently, it is permitted by default and a warning is issued.

If you see a warning like this, contact the maintainers of the tool or library. The second line of the warning names the exact JAR file whose code used reflection to access an internal part of the JDK.

By default, a maximum of one warning about reflective access is issued in the lifetime of the process started by the java launcher. The exact timing of the warning depends on the behavior of tools and libraries performing reflective–access operations. The warning may appear early in the lifetime of the process, or a long time after startup.

You can disable the warning message on a library-by-library basis by using the --add-opens command line flag. For example, you can start Jython in the following way:

This time, the warning is not issued because the java invocation explicitly acknowledges the reflective access. As you can see, you may need to specify multiple --add-opens flags to cover all of the reflective access operations that are attempted by libraries on the class path.

To better understand the behavior of tools and libraries, you can use the --illegal-access=warn command line flag. This flag causes a warning message to be issued for every illegal reflective-access operation. In addition, you can obtain detailed information about illegal reflective-access operations, including stack traces, by setting --illegal-access=debug.

If you have updated libraries, or when you get them, then you can experiment with using the --illegal-access=deny command line flag. It disables all reflective-access operations except for those enabled by other command-line options, such as --add-opens. This will be the default mode in a future release.

There are two options that allow you to break encapsulation in specific ways. You could use these in combination with --illegal-access=deny, or, as already mentioned, to suppress warnings.

If you need to use an internal API that has been made inaccessible, then use the --add-exports runtime option. You can also use --add-exports at compile time to access internal APIs.

If you have to allow code on the class path to do deep reflection to access nonpublic members, then use the --add-opens option.

If you want to suppress all reflective access warnings, then use the --add-exports and --add-opens options where needed.

--add-exports

If you must use an internal API that has been made inaccessible by default, then you can break encapsulation using the --add-exports command-line option.

where <source-module> and <target-module> are module names and <package> is the name of a package.

The --add-exports option allows code in the target module to access types in the named package of the source module if the target module reads the source module.

As a special case, if the <target-module> is ALL-UNNAMED, then the source package is exported to all unnamed modules, whether they exist initially or are created later on. For example:

--add-exports java.management/sun.management=ALL-UNNAMED

This example allows code in all unnamed modules (code on the class path) to access the public members of public types in java.management/sun.management. If the code on the class path attempts to do deep reflection to access nonpublic members, then the code fails.

If an application oldApp that runs on the classpath must use the unexported com.sun.jmx.remote.internal package of the java.management module, then the access that it requires can be granted in this way:

--add-exports java.management/com.sun.jmx.remote.internal=ALL-UNNAMED

You can also break encapsulation with the JAR file manifest:

Add-Exports:java.management/sun.management

Use the --add-exports option carefully. You can use it to gain access to an internal API of a library module, or even of the JDK itself, but you do so at your own risk. If that internal API changes or is removed, then your library or application fails.

--add-opens

If you have to allow code on the class path to do deep reflection to access nonpublic members, then use the --add-opens runtime option.

Some libraries do deep reflection, meaning setAccessible(true), so they can access all members, including private ones. You can grant this access using the --add-opens option on the java command line. No warning messages are generated as a result of using this option.

If --illegal-access=deny, and you see IllegalAccessException or InaccessibleObjectException messages at runtime, you could use the --add-opens runtime option, basing the arguments upon the information shown in the exception message.

The syntax for --add-opens is:

--add-opens module/package=target-module(,target-module)*

This option allows <module> to open <package> to <target-module>, regardless of the module declaration.

As a special case, if the <target-module> is ALL-UNNAMED, then the source package is exported to all unnamed modules, whether they exist initially or are created later on. For example:

--add-opens java.management/sun.management=ALL-UNNAMED

This example allows all of the code on the class path to access nonpublic members of public types in the java.management/sun.management package.

Note:

If you are using the JNI Invocation API, including, for example, a Java Web Start JNLP file, you must include an equals sign between --add-opens and its value.

The equals sign between --add-opens and its value is optional on the command line.

New Version-String Scheme

JDK 10 introduced some minor changes, to better accommodate the time-based release model, to the version-string scheme introduced in JDK 9. JDK 11 retains the version string format that was introduced in JDK 10.

If your code relies on the version-string format to distinguish major, minor, security, and patch update releases, then you may need to update it.

Prior releases produced two types of runtime images: the JRE, which was a complete implementation of the Java SE Platform, and the JDK, which included the entire JRE in a jre/ directory, plus development tools and libraries.

In JDK 9 and and JDK 10, the JDK and JRE are two types of modular runtime images, where each contains the following directories:

bin: contains binary executables.

conf: contains .properties, .policy, and other kinds of files intended to be edited by developers, deployers, and end users. These files were formerly found in the lib directory or its subdirectories.

lib: contains dynamically linked libraries and the complete internal implementation of the JDK.

In JDK 9 and JDK 10, there are still separate JDK and JRE downloads, but each has the same directory structure. The JDK image contains the extra tools and libraries that have historically been found in the JDK. There are no jdk/ versus jre/ wrapper directories, and binaries (such as the java command) aren’t duplicated.

New Class Loader Implementations

JDK 9 and later releases maintain the hierarchy of class loaders that existed since the 1.2 release. However, the following changes have been made to implement the module system:

The application class loader is no longer an instance of URLClassLoader but, rather, of an internal class. It is the default loader for classes in modules that are neither Java SE nor JDK modules.

The extension class loader has been renamed; it is now the platform class loader. All classes in the Java SE Platform are guaranteed to be visible through the platform class loader. In addition, the classes in modules that are standardized under the Java Community Process but not part of the Java SE Platform are guaranteed to be visible through the platform class loader.

Just because a class is visible through the platform class loader does not mean the class is actually defined by the platform class loader. Some classes in the Java SE Platform are defined by the platform class loader while others are defined by the bootstrap class loader. Applications should not depend on which class loader defines which platform class.

The changes that were implemented in JDK 9 may impact code that creates class loaders with null (that is, the bootstrap class loader) as the parent class loader and assumes that all platform classes are visible to the parent. Such code may need to be changed to use the platform class loader as the parent (see ClassLoader.getPlatformClassLoader).

The platform class loader is not an instance of URLClassLoader, but, rather, of an internal class.

The bootstrap class loader is still built-in to the Java Virtual Machine and represented by null in the ClassLoader API. It defines the classes in a handful of critical modules, such as java.base. As a result, it defines far fewer classes than in JDK 8, so applications that are deployed with -Xbootclasspath/a or that create class loaders with null as the parent may need to change as described previously.

Removed rt.jar and tools.jar in JDK 9

Class and resource files previously stored in lib/rt.jar, lib/tools.jar, lib/dt.jar and various other internal JAR files are stored in a more efficient format in implementation-specific files in the lib directory.

The removal of rt.jar and similar files leads to issues in these areas:

Starting from JDK 9, ClassLoader.getSystemResource doesn’t return a URL pointing to a JAR file (because there are no JAR files). Instead, it returns a jrt URL, which names the modules, classes, and resources stored in a runtime image without revealing the internal structure or format of the image.

For example:

ClassLoader.getSystemResource("java/lang/Class.class");

When run on JDK 8, this method returns a JAR URL of the form:

jar:file:/usr/local/jdk8/jre/lib/rt.jar!/java/lang/Class.class

which embeds a file URL to name the actual JAR file within the runtime image.

A modular image doesn’t contain any JAR files, so URLs of this form make no sense. On JDK 9 and later releases, this method returns:

jrt:/java.base/java/lang/Class.class

The java.security.CodeSource API and security policy files use URLs to name the locations of code bases that are to be granted specific permissions. See Policy File Syntax in Java Platform, Standard Edition Security Developer's Guide. Components of the runtime system that require specific permissions are currently identified in the conf/security/java.policy file by using file URLs.

Older versions of IDEs and other development tools require the ability to enumerate the class and resource files stored in a runtime image, and to read their contents directly by opening and reading rt.jar and similar files. This isn’t possible with a modular image.

Removed Extension Mechanism in JDK 9

In JDK 8 and earlier, the extension mechanism made it possible for the runtime environment to find and load extension classes without specifically naming them on the class path. Starting from JDK 9, if you need to use the extension classes, ensure that the JAR files are on the class path.

In JDK 9 and JDK 10, the javac compiler and java launcher will exit if the java.ext.dirs system property is set, or if the lib/ext directory exists. To additionally check the platform-specific systemwide directory, specify the -XX:+CheckEndorsedAndExtDirs command-line option. This causes the same exit behavior to occur if the directory exists and isn’t empty. The extension class loader is retained in JDK 9 (and later releases) and is specified as the platform class loader (see getPlatformClassLoader.) However, in JDK 11, this option is obsolete and a warning is issued when it is used.

The following error means that your system is configured to use the extension mechanism:

<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; Use -classpath instead.
.Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

You’ll see a similar error if the java.ext.dirs system property is set.

To fix this error, remove the ext/ directory or the java.ext.dirs system property.

Removed Endorsed Standards Override Mechanism

The java.endorsed.dirs system property and the lib/endorsed directory are no longer present. The javac compiler and java launcher will exit if either one is detected.

Starting from JDK 9, you can use upgradeable modules or put the JAR files on the class path.

This mechanism was intended for application servers to override components used in the JDK. Packages to be updated would be placed into JAR files, and the system property java.endorsed.dirs would tell the Java runtime environment where to find them. If a value for this property wasn’t specified, then the default of $JAVA_HOME/lib/endorsed was used.

In JDK 8, you can use the -XX:+CheckEndorsedAndExtDirs command-line argument to check for such directories anywhere on the system.

In JDK 9 and later releases, the javac compiler and java launcher will exit if the java.endorsed.dirs system property is set, or if the lib/endorsed directory exists.

The following error means that your system is configured to use the endorsed standards override mechanism:

<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs
in modular form will be supported via the concept of upgradeable modules.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

You’ll see a similar error if the java.endorsed.dirs system property is set.

To fix this error, remove the lib/endorsed directory, or unset the java.endorsed.dirs system property.

Windows Registry Key Changes

The Java 11 installer creates these Windows registry keys when installing the JDK:

“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK”

“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\11”

If there are two versions of JDK installed, then there will be two different Windows registry keys are created. For example, if JDK 11.0.1 is installed with JDK 11, then the installer creates the another Windows registry key as shown:

“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK”

“HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\11.0.1”

Removed or Changed APIs

This section highlights APIs that have been made inaccessible, removed, or altered in their default behavior. You may encounter the issues described in this section when compiling or running your application.

Removed APIs in JDK 9 and JDK 10

The following are some important APIs that have been removed from JDK 9 and JDK 10 releases.

Removed java.* APIs

The Java team is committed to backward compatibility. If an application runs in JDK 8, then it will run on JDK 9 and later releases as long as it uses APIs that are supported and intended for external use.

These include:

JCP standard, java.*, javax.*

JDK-specific APIs, some com.sun.*, some jdk.*

Supported APIs can be removed from the JDK, but only with notice. Find out if your code is using deprecated APIs by running the static analysis tool jdeprscan.

java.* APIs that were removed in JDK 9 include the previously deprecated methods from the java.util.logging.LogManager and java.util.jar.Pack200 packages:

java.awt.peer Not Accessible

The java.awt.peer and java.awt.dnd.peer packages aren’t accessible, starting in JDK 9. The packages were never part of the Java SE API, despite being in the java.* namespace.

All methods in the Java SE API that refer to types defined in these packages were removed from JDK 9. Code that calls a method that previously accepted or returned a type defined in these packages no longer compiles or runs.

There are two common uses of the java.awt.peer classes. You should replace them as follows:

Removed com.sun.image.codec.jpeg Package

The nonstandard package com.sun.image.codec.jpeg has been removed. Use the Java Image I/O API instead.

The com.sun.image.codec.jpeg package was added in JDK 1.2 as a nonstandard way of controlling the loading and saving of JPEG format image files. It has never been part of the platform specification.

In JDK 1.4, the Java Image I/O API was added as a standard API, residing in the javax.imageio package. It provides a standard mechanism for controlling the loading and saving of sampled image formats and requires all compliant Java SE implementations to support JPEG based on the Java Image I/O specification.

Removed Tools Support for Compact Profiles

Starting in JDK 9, you can choose to build and run your application against any subset of the modules in the Java runtime image, without needing to rely on predefined profiles.

Profiles, introduced in Java SE 8, define subsets of the Java SE Platform API that can reduce the static size of the Java runtime on devices that have limited storage capacity. The tools in JDK 8 support three profiles, compact1, compact2, and compact3. For the API composition of each profile, see Detailed Profile Composition and API Reference in the JDK 8 documentation.

In JDK 8, you use the -profile option to specify the profile when running the javac and java commands. Starting in JDK 9, the -profile option is supported by javac only in conjunction with the --release 8 option, and isn’t supported by java.

JDK 9 and later releases let you choose the modules that are used at compile and run time. By specifying modules with the new --limit-modules option, you can obtain the same APIs that are in the compact profiles. This option is supported by both the javac and java commands, as shown in the following examples:

javac --limit-modules java.base,java.logging MyApp.java

java --limit-modules java.base,java.logging MyApp

The packages specified for each profile in Java SE 8 are exported, collectively, by the following sets of modules:

You can use the jdeps tool to do a static analysis of the Java packages that are being used in your source code. This gives you the set of modules that you need to execute your application. If you had been using the compact3 profile, for example, then you may see that you don’t need to include that entire set of modules when you build your application. See jdeps in Java Platform, Standard Edition Tools Reference.

Deployment

Java deployment technologies were deprecated in JDK 9 and removed in JDK 11.

Use the jlink tool introduced with JDK 9 to package and deploy dedicated runtimes rather than relying on a pre-installed system JRE.

Removed Launch-Time JRE Version Selection

The ability to request a version of the JRE that isn’t the JRE being launched at launch time is removed, starting in JDK 9.

Modern applications are typically deployed using Java Web Start (JNLP), native OS packaging systems, or active installers. These technologies have their own methods to manage the JREs needed, by finding or downloading and updating the required JRE, as needed. This makes the launcher's launch-time JRE version selection obsolete.

In the previous releases, you could specify what JRE version (or range of versions) to use when starting an application. Version selection was possible through both a command-line option and manifest entry in the application's JAR file.

Starting in JDK 9, the java launcher is modified as follows:

Emits an error message and exits if the -version: option is given on the command line.

Emits a warning message and continues if the JRE-Version manifest entry is found in a JAR file.

JNLP Specification Update

The JNLP file syntax conforms to the XML specification and all JNLP files should be able to be parsed by standard XML parsers.

JNLP files let you specify complex comparisons. Previously, this was done by using the ampersand (&), but this isn’t supported in standard XML. If you’re using & to create complex comparisons, then replace it with &amp; in your JNLP file. &amp; is compatible with all versions of JNLP.

Comparing numeric version element types against nonnumeric version element types.

Previously, when an int version element was compared with another version element that couldn’t be parsed as an int, the version elements were compared lexicographically by ASCII value.

Starting in JDK 9, if the element that can be parsed as an int is a shorter string than the other element, it will be padded with leading zeros before being compared lexicographically by ASCII value. This ensures there can be no circularity.

In the case where both version comparisons and a JNLP servlet are used, you should use only numeric values to represent versions.

Security Updates in JDK 9

Some security-related defaults have changed, starting from JDK 9.

JCE Jurisdiction Policy File Default is Unlimited

If your application previously required the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files, then you no longer need to download or install them. They are included in the JDK and are activated by default.

If your country or usage requires a more restrictive policy, the limited Java cryptographic policy files are still available.

If you have requirements that are not met by either of the policy files provided by default, then you can customize these policy files to meet your needs.

See the crypto.policy Security property in the <java-home>/conf/security/java.security file, or Cryptographic Strength Configuration in the Java Platform, Standard Edition Security Developer's Guide.

You are advised to consult your export/import control counsel or attorney to determine the exact requirements.

Create PKCS12 Keystores

We recommend that you use the PKCS12 format for your keystores. This format, which is the default keystore type, is based on the RSA PKCS12 Personal Information Exchange Syntax Standard.

Removed GC Options

The following GC combinations will cause your application to fail to start in JDK 9 and later releases:

DefNew + CMS

ParNew + SerialOld

Incremental CMS

The foreground mode for CMS has also been removed. The command-line flags that were removed are -Xincgc, -XX:+CMSIncrementalMode, -XX:+UseCMSCompactAtFullCollection, -XX:+CMSFullGCsBeforeCompaction, and -XX:+UseCMSCollectionPassing.

The command-line flag -XX:+UseParNewGC no longer has an effect. The ParNew flag can be used only with CMS and CMS requires ParNew. Thus, the -XX:+UseParNewGC flag has been deprecated and is eligible for removal in a future release.

Changes to GC Log Output

Garbage collection (GC) logging uses the JVM unified logging framework, and there are some differences between the new and the old logs. Any GC log parsers that you’re working with will probably need to change.

You may also need to update your JVM logging options. All GC-related logging should use the gc tag (for example, —Xlog:gc), usually in combination with other tags. The —XX:+PrintGCDetails and -XX:+PrintGC options have been deprecated.

Removed the JVM TI hprof Agent

The hprof agent library has been removed.

The hprof agent was written as demonstration code for the JVM Tool Interface and wasn’t intended to be a production tool. The useful features of the hprof agent have been superseded by better alternatives, including some that are included in the JDK.

For creating heap dumps in the hprof format, use a diagnostic command (jcmd) or the jmap tool:

Removed Support for the IIOP Transport from the JMX RMIConnector

The IIOP transport support from the JMX RMI Connector along with its supporting classes have been removed from the JDK.

In JDK 8, support for the IIOP transport was downgraded from required to optional. This was the first step in a multirelease effort to remove support for the IIOP transport from the JMX Remote API. In JDK 9, support for IIOP was removed completely.

Public API changes include:

The javax.management.remote.rmi.RMIIIOPServerImpl class has been deprecated. Upon invocation, all its methods and constructors throw java.lang.UnsupportedOperationException with an explanatory message.

Removed native2ascii Tool

The native2ascii tool has been removed from the JDK. Because JDK 9 and later releases support UTF-8 based properties resource bundles, the conversion tool for UTF-8 based properties resource bundles to ISO-8859-1 is no longer needed.

Removed macOS-Specific Features

This section includes macOS-specific features that have been removed, starting in JDK 9.

Platform-Specific Desktop Features

The java.awt.Desktop class contains replacements for the APIs in the Apple–specific com.apple.eawt and com.apple.eio packages. The new APIs supersede the macOS APIs and are platform-independent.

The APIs in the com.apple.eawt and com.apple.eio packages are encapsulated, so you won’t be able to compile against them in JDK 9 or later releases. However, they remain accessible at runtime, so existing code that is compiled to old versions continues to run. Eventually, libraries or applications that use the internal classes in the apple and com.apple packages and their subpackages will need to migrate to the new API.

The com.apple.concurrent and apple.applescript packages are removed without any replacement.

Removed AppleScript Engine

The AppleScript engine, a platform-specific javax.script implementation, has been removed without any replacement in the JDK.

The AppleScript engine has been mostly unusable in recent releases. The functionality worked only in JDK 7 or JDK 8 on systems that already had Apple's version of the AppleScriptEngine.jar file on the system.

Next Steps

After you have your application working on JDK 11, here are some suggestions that can help you get the most from the Java SE Platform:

If needed, cross-compile to an older release of the platform using the new -–release flag in the javac tool.

Take advantage of your IDE’s suggestions for updating your code with the latest features.

Find out if your code is using deprecated APIs by running the static analysis tool jdeprscan. As already mentioned in this guide, APIs can be removed from the JDK, but only with advance notice.

Get familiar with new features like multi-release JAR files (see jar) .

This guide will help you migrate your application from Oracle JDK 8 to Oracle JDK 10.

This software and related documentation are provided under a license
agreement containing restrictions on use and disclosure and are protected by
intellectual property laws. Except as expressly permitted in your license agreement or
allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license,
transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by
any means. Reverse engineering, disassembly, or decompilation of this software, unless
required by law for interoperability, is prohibited.

The information contained herein is subject to change without notice
and is not warranted to be error-free. If you find any errors, please report them to us
in writing.

If this is software or related documentation that is delivered to the
U.S. Government or anyone licensing it on behalf of the U.S. Government, then the
following notice is applicable:

U.S. GOVERNMENT END USERS: Oracle programs, including any operating
system, integrated software, any programs installed on the hardware, and/or
documentation, delivered to U.S. Government end users are "commercial computer software"
pursuant to the applicable Federal Acquisition Regulation and agency-specific
supplemental regulations. As such, use, duplication, disclosure, modification, and
adaptation of the programs, including any operating system, integrated software, any
programs installed on the hardware, and/or documentation, shall be subject to license
terms and license restrictions applicable to the programs. No other rights are granted
to the U.S. Government.

This software or hardware is developed for general use in a variety of
information management applications. It is not developed or intended for use in any
inherently dangerous applications, including applications that may create a risk of
personal injury. If you use this software or hardware in dangerous applications, then
you shall be responsible to take all appropriate fail-safe, backup, redundancy, and
other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim
any liability for any damages caused by use of this software or hardware in dangerous
applications.

Oracle and Java are registered trademarks of Oracle and/or its
affiliates. Other names may be trademarks of their respective owners.

Intel and Intel Xeon are trademarks or registered trademarks of Intel
Corporation. All SPARC trademarks are used under license and are trademarks or
registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the
AMD Opteron logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX
is a registered trademark of The Open Group.

This software or hardware and documentation may provide access to or
information about content, products, and services from third parties. Oracle Corporation
and its affiliates are not responsible for and expressly disclaim all warranties of any
kind with respect to third-party content, products, and services unless otherwise set
forth in an applicable agreement between you and Oracle. Oracle Corporation and its
affiliates will not be responsible for any loss, costs, or damages incurred due to your
access to or use of third-party content, products, or services, except as set forth in
an applicable agreement between you and Oracle.