So Java 9 is coming out, and you are probably excited to try building and running your own software on it. As you start planning your migration, there are some things to consider. Here are some steps to migrating your code.
Find your inappropriate dependencies
If you are relying on Sun internal packages (like sun.misc.*), your code will break running on Java 9 because of new restrictions that effectively hide these classes. In theory even updates to Java 6 or Java 7 could remove these classes because they are not part of the Java spec. Unlikely, yes, but possible. Even if you don’t depend on Sun internal packages yourself, if you have transitive dependencies on libraries that do, then they will break and you will break! You can review the compatibility of popular FOSS libraries (or add your own) on OpenJDK’s quality outreach page.
Later versions of 7 or 8 will give compiler warnings:
[WARNING] /path/to/some/UnsafeUsingClass.java:[79,15] sun.misc.Unsafe is internal proprietary API and may be removed in a future release
Also, Java 8 provides a program called “jdeps” to find these dependencies explicitly. To run the JDeps tool, just direct it towards your build artifacts with “jdeps -cp . -jdkinternals *.jar” It even helpfully tells you where to go to find replacements for your Unsafe reference!
Here I direct it towards one of my own open source projects with an artificially introduced reference to sun.misc.Unsafe:
jdeps -cp . -jdkinternals *.jar zee-0.9.4-SNAPSHOT.jar -> /home/jay/opt/jdk1.8.0_92/jre/lib/rt.jar zee.engine.EquationProcessor (zee-0.9.4-SNAPSHOT.jar) -> sun.misc.Unsafe JDK internal API (rt.jar) . -> /home/jay/opt/jdk1.8.0_92/jre/lib/rt.jar -> sun.misc.Unsafe JDK internal API (rt.jar) Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break your application. Please modify your code to eliminate dependency on any JDK internal APIs. For the most recent update on JDK internal API replacements, please check: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
There’s also a JDEPS Maven Plugin (which does the same thing as jdeps)
Fix inappropriate dependencies where you can
If you find you do have a dependency on these internal classes, you can find the recommended replacements on the JDeps website. Each instance needs to be reviewed and handled on a case-by-case basis to ensure that the recommended fix works for your specific use case. This is really what you need to do long term.
Isolate inappropriate dependencies
If you are pressed for time (and aren’t we all?!) you can choose to manage the dependency by isolating it to ease a future transition. If you REALLY need to depend on an internal API, break it out into a library to enable you to evolve your code independently and make it clear where to change your dependencies.
Leverage Multi-Release Jar Files
Multi-Release Jar Files, a new feature in Java 9, lets you include multiple versions of a class to be loaded depending on the version of the JVM loading the jar. Older JVM’s will just ignore the later versions of a class, but Java 9 and later JVM’s will recognize the format and use the later version of the class. You can use this to your advantage when migrating: leave your references to sun.misc.* in your existing code, fix them with new versions of your classes, and distribute your old classes and fixed classes together in the same JAR. This way Java 7 or 8 JVM’s can use your existing code as-is, and Java 9 JVM’s can use your fixed classes which are using Java 9 language features to replace the inappropriate dependencies which are now missing in Java 9. This approach eases the transition, especially for public libraries or distributable software where you don’t necessarily control the version of JVM running your code.
If you only remember one thing: JDEPS!