About a year ago, I joined Hackages team to start working on a new training about "Migrating Java App from version 8 to 12". We had an exciting challenge on our hands: we needed to build content from scratch to help Java developers to move forward with new versions of Java.
Indeed since 2017, Oracle & the Java community announced its shift to a new 6-month cadence for Java.
Over time applications needs to be evolved to follow the evolution of the Java language. This resulted in a decision to upgrading our training.
With these changes, we need to be able to switch between different versions of Java without a headache. Here's how to make it easier to manage multiple versions of Java on your Mac.
Homebrew is free and open-source package management software for macOS that makes it easy to install programs. Installation is done in a command-line
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
JAVA_HOME is an integral part of the workflow of a Java developer. We need it to build, compile, and launch our projects.
jEnv is a command-line solution that allows us to manage the JAVA_HOME environment variable.
The command to install jEnv via Homebrew is as follows:
brew install jenv
Now that jEnv is installed, we can add the different versions of Java that we need.
We can already list the versions listed with the following command:
$ jenv versions system 1.8
Many things have changed since Java 8, not just in terms of features in the language. Oracle has started publishing two different versions, each with a different license (a commercial version that you must pay to use in production and an open-source OpenJDK version) and has modified its update and support templates. This new policy created some confusion in the community, but in the end, it gave us more choice over the JDK we use. We must consider both the options available to us and what we expect from the JDK.
To install a new version of Java, we use Homebrew again:
brew cask install adoptopenjdk13
The last thing to do is now to add this new version to Jenv.
jenv add /Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home
You can verify if the version correctly added.
$ jenv versions *system 1.8 13.0.1
You can now change the version fo your choice.
$ jenv global 13.0.1
Open a command prompt and check java version to make sure you have change for the new version of Java.
$ java -version openjdk version "13.0.1" 2019-10-15 OpenJDK Runtime Environment AdoptOpenJDK (build 13.0.1+9) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 13.0.1+9, mixed mode, sharing)
And voilà 😎. Now we can switch versions as we want.
Each upgrade process will be specific to the migrated application. However, some good basic practices make the process easier. These described in the order in which you should address them, and you will see that for the first few steps, you do not even need to use an updated JDK.
Warnings are there for a reason, and if you read them, they often talk about features that may disappear in the future. If you are working with Java 8, on a JDK 8, and you see obsolescence warnings or feature warnings that you should not use, correct these warnings before attempting to switch to a JDK more recent.
Note that deprecation is taken much more seriously in recent versions of Java and that Java 10 and Java 11 have removed APIs.
If you use Maven or Gradle, you must upgrade.
Gradle 6.0 introduced Java 13 support, so we should use at least Gradle in version 5.0 to use Java version beyond 9. The current release version is 6.2.2.
We must use at least version 3.5.0 (the current version is 3.6.3), and we must make sure that the Maven compiler plugin is at least version 3.8:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <release>11</release> <!-- or 12 or 13 --> </configuration> </plugin>
Some of the problems you may have heard about migrating to Java 9 or later are problems encountered (and potentially corrected) by libraries and frameworks. For example, many frameworks use reflection and underlying internal APIs. For your application to have the best chance of continuing to work correctly, you must make sure that all your dependencies are up to date. Many libraries have already been updated to work with Java 9 and beyond, and there is an ongoing effort by the community to ensure that this continues.
Only when everything works, all your tests will run, and everything looks good, and maybe after some time in production, you can consider using the new language features.
Also, remember that even though Java version 9 has introduced the module system in Java, applications do not need to use it at all, even if they have migrated to a version that supports it.