Now that JDK 10 has been out for a few weeks, I thought it would be a good idea to write a follow up to one of my earlier posts. The previous post described all the changes in JDK 9 that might cause problems for application migration. Since all the changes in JDK 9 are also in JDK 10, if you’re planning to move an application from JDK 8 or earlier, you should probably read both posts.
Although only having six months of development, JDK 10 contains (by my count) 109 new features and APIs.
Language
From a feature perspective, the most significant is local-variable type inference. Without going into details, we now have the ability to use var in place of an explicit type definition for local variables and let the compiler infer the specific type for us. How does that impact backwards compatibility? Not much as, thankfully, var has not been made a reserved word. I’m sure there are plenty of developers who have at some point used var as a variable name, even though it’s probably not an excellent choice. Instead, var is now a reserved type. The net effect of this is that this code is valid:
var var = “Great variable name choice!”;
but this code, which would have compiled on JDK 9 and earlier, is no longer valid:
public class var { public var() { System.out.println(“Hello from var!”); } }
If you try and compile this with JDK 10 you will get the following errors:
var.java:1: error: 'var' not allowed here public class var { ^ as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations var.java:2: error: 'var' is not allowed here public var() { ^ 2 errors
Of course, I’m sure nobody has created a class called var, as that goes against the naming convention for Java classes. If you have, just renaming it to Var will solve at least one of your problems.
Deleted API Elements
The next thing to look at is the standard API elements that have been removed in JDK 10. Until JDK 9, no deprecated API elements had ever been removed (despite there being over four hundred of them). The changes in JDK 9 were small, and those in JDK 10 are not much bigger. Here’s the list of things that will require changes if you’ve used them in your code.
Firstly, a number of classes in the com.sun.security.auth package have been removed, which is part of the Java Authentication and Authorisation Service (JAAS) API.
- PolicyFile: Replaced by sun.security.provider.PolicyFile.
- SolarisNumericGroupPrincipal: Replaced by UnixNumericGroupPrincipal
- SolarisNumericUserPrincipal: Replaced by UnixNumericUserPrincipal
- SolarisPrincipal: Replaced by UnixPrincipal
- X500Principal: A new X500Principal class is available in the javax.security.auth.x500 package contained in the java.base module.
Two methods have been removed from the related com.sun.security.auth.module package:
- SolarisLoginModule:
- SolarisSystem:
The java.lang.SecurityManager also has several elements removed. The inCheck field has been removed as well as the following methods:
- classDepth
- classLoaderDepth
- currentClassLoader
- currentLoadedClass:
- getInCheck
- inClass
- inClassLoader
All these elements are ancient, dating from pre-JDK 1.2.
Two obsolete internationalisation methods have been removed from the java.lang.Runtime class. According to the release notes, there are no known users of these APIs. I’m willing to bet someone, somewhere has.
- getLocalizedInputStream
- getLocalizedOutputStream
The com.sun.java.browser.plugin2.DOM, and sun.plugin.dom.DOMObject APIs have been removed. If you have used either of these can use netscape.javascript.JSObject. This is in preparation for the removal of Applet support in JDK 11.
The way that specific Look and Feels are selected has changed. For the Nimbus and Aqua Look and Feel you should use these method calls.
Nimbus:
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
Aqua:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Miscellaneous Changes
There are a couple of minor changes that might affect application portability, although they are more likely to affect build scripts.
The javah command has been removed. This has been used in the past to generate header files for JNI code. The way to do this in JDK 10 is to use the -h flag on javac, which does the same thing.
The policytool has been removed. The tool generates a text file and, typically, the only place where changes need to be made are in the $JAVA_HOME/conf/security/java.policy
file.
RMI Server-Side Multiplex Protocol Support, which was disabled in JDK 9, has now been removed. This is another one of those ancient and obscure things that likely maybe only one person in the world uses. The protocol was introduced back in JDK 1.0.2 to work around a problem in the Netscape Navigator browser when running applets that used RMI. The feature was deprecated in JDK 1.2.2.
A number of obsolete -X command line options have been removed. Specifically:
- -Xoss
- -Xsqnopause
- -Xoptimize
- -Xboundthreads
- -Xusealtsigs
The -d32 and -d64 command line options, which only really had any effect when running on Solaris, have been removed. There is now only a 64-bit version of the JDK binary from Oracle.
Finally, the JDK 6/JDK 7/JDK 8 standard Doclets have been removed.
Conclusions
There are a number of things that have been removed in JDK 10, but I doubt any of these will affect a significant number of (or in most cases, any) applications. Clearly, the big change in terms of migrating to JDK 10 is ensuring that code, including third-party libraries and frameworks, work correctly with the Java Platform Module System. If you’ve already tested your applications with JDK 9 moving to JDK 10 should be easy.
Let’s wait and see what JDK 11 brings…