JavaOne this year left us with some big announcements – one of which was the arrival of Java 9 (finally). Whilst there are some nice new features including simpler Collection methods and modules, there is a bit of a transition required to move onto Java 9 and make the most out of it.
I decided to write this blog post to highlight 4 potentially useful pieces of information that can make it easier to plan and carry out the transition process. Oracle have published their own Transition Page which is also very useful and goes into more detail about certain topics discussed in this post.
1) Not every project can become modular
Before I get into some of the other aspects please remember using Project Jigsaw may not be possible for everyone. As Mark Reinhold pointed out in the Java Keynote – Project Jigsaw can break some things and is therefor not for every project. In cases where this applies though you can still use the Classpath as it is still supported in Java 9.
2) Regression Tests
Before making any changes to your code base you need to make sure you have adequate regression tests in place. When moving to Java 9 you may have to refactor methods, move packages around and change implementation details to get it to work with the new JDK. Whilst carrying all this out you may unknowingly break a feature or several so you need to make sure that any changes don’t break your current builds. Some of these changes whilst supported in Java 9 could be unsupported in previous versions. It will be worth your time to review, update and add any tests that you currently have to make sure they are up to scratch.
3) Dealing with Current Modules
For those who can migrate to Java 9 creating a module is as simple as adding a module-info.java file in the package you are converting. The module-info.java file contains all the key module data including the modules name. This will require adding the requires tag (modules the current module depends on) and exports tag (for publicly available classes) among other tags. Due to having to state dependencies it would be best to convert dependent modules first then move onto modules that will use those dependencies. A good overview for modules can be found here.
Note that a package cannot be split into multiple modules and there cannot be root classes. You therefore need to split up packages before creating your module-info.java because it can become messy if you split them afterwards due to having duplicated or unneeded exports and requires tags. Also the requires tag can help find missing values defined in your classes import statements.
Furthermore, you cannot downgrade dependencies whose parents have no module name. For example if you have a class A that has B as a dependency then you need to make B a module first. If B however extends class C then you need to make C a module before B.
4) Deprecated Classes and Removed Internal API Access
Java 9 also added some extra encapsulation features to the code base and is tidying up by removing old deprecated API’s or their methods from the code base. Some internal API’s will have restricting access and others will be removed like java.lang.Thread.destroy(). You can see which APIs are being encapsulated and which Deprecated API’s are being removed on the Oracle website.
To help see if any of the above will affect your code you can use two tools built into the Java 9 JDK to find if you have any potential issues with relying on internal or deprecated API’s:
– Jdeps: can spot dependencies on internal API’s and third party JARs
– jdeprscan: can spot usages of any deprecated API’s
At the moment if you run the Java 9 code you may get Illegal deep reflection warnings which occur when you are accessing some of these redundant/internal API’s and whilst your code will build for now these warnings will become errors in the future. May be worth planning to find alternative solutions instead of relying on their classes.
Do you have any other migration tasks that could be useful for when people start moving to Java 9?