Upgrading to Java 9
Ever since Java 9 was released last fall, I have been wanting to upgrade our software at work to the new platform. I am not interested in the new module stuff, mostly I just want the convenience methods like List.of(), and the platform improvements. I think G1 by default looks good, the new representation for strings to save memory looks like a huge win, and all the performance numbers that I have seen show it to be a big win. Unfortunately this is not as straight forward as one should hope.
Step 1 – Spring Support
Even though Spring 5.0 was released back in December I think which fully supports Java 9, Spring Boot 2.0 is not yet released. I believe it is in RC2 now and about to be released in the next week or so, but at this point we are less than a month away from Java 10, before we will have proper Spring Boot support in Java 9. All of our microservices are currently running on Spring Boot 1.5.10 except for one. It is still running on the 1.3.x version of Spring boot, which brings us to our second Spring issue to resolve. Some contractors that originally started that service did a hack to lazy load @Formula s in hibernate. While this worked in Hibernate 4.x in Hibernate 5 the hack no longer worked so we can’t even update this service until we refactor those entities and move that data into views. That is still a work in progress. The other microservices could be moved to 2.0 when it comes out, but I think their is a consensus that we don’t want to move to 2.0 until we have all our services to a place where we could do that.
Step 2 – Gradle
We are currently running gradle 3.5.1. Going to Java 9 is going to require Gradle 4.2 (which is also a requirement for the Spring Boot 2.0 Gradle plugin). Normally this is no big deal upgrade the gradle.build file edit the wrapper portion to the new version run ./gradlew wrapper and check in the new gradle wrapper. But in this case we still have a developer running on IntelliJ 2016.1 and another on 2016.2. They would have to upgrade to at least 2017.2 in order for the new gradle to work with their IDE. So we will need to convince the whole team to update their IDE if they haven’t already ideally at that point to 2018.1.
Step 3 – FlywayDB
We are currently using Flyway DB 4.2.0. This didn’t work with Java 9 when I was testing it, so we need to go to 5.0.x. Additionally Spring Boot 2.0 requires Flyway 5.0.x. Ideally we want to upgrade this ahead of Spring to minimize risk. Bring the new flyway into production and then once we are satisfied that it doesn’t break anything upgrade Spring Boot.
Step 4 – Docker Containers
Once we have all that software in place we then will have to update our docker containers to pull in the new JVM. It sounds like in Java 9 Linux, OpenJDK ships with an empty certificate store. So that means finding a Oracle or Azul docker container as our base. We then have to verify that New Relic works with Java 9 so we have our container monitoring. After doing all that we can update our base VM to be Java 9.
Step 5 – Update Jenkins
We will need to add a new VM to Jenkins so that as different builds switch to the new Java 9 container we also switch to compiling them with the Java 9 VM (though with the Java 8 flags still at this point).
Will the pain never end…
Finally after doing everything listed above we could change our compiler flags to 9 and start using the features. It is still a painful road to walk to get us there. At this point it feels like by the time we finish the work that needs to be done (as obviously we need to be shipping features and bug fixes, while we lay the foundation for this on the side) Java 11 will be out and we will be moving to that.
Even though Java 9 support is so close to being out in Spring Boot I still feel like I am at least 6 months away from getting to use any of it. This feels much more painful than when I moved an App from Java 7 -> 8. At that point I think it was just a matter of coordinating a JBoss container upgrade from 6.0.1 to 6.4. After we got that into production we updated the VM to Java 8 (still with everything compiling on 7). Then we upgraded our Jenkins machine to have Java 8 for the compiler, and finally we updated our maven pom to use source and target of 8. I wonder if anyone Spring shops will even make it to 9 or if everyone is holding out for 11 at this point (also to get the LTS release). While I really like the sound of the 6 month release cadence actually getting the dependencies in place and lined up to do an upgrade will probably mean most enterprises just end up going from LTS release to LTS release and I would guess that Java 9 and 10 see very little use running production code and mostly will just be things for developers to play with on their machines.