macOS easy JDK switching

As a freelance developer and part-time blogger, I need to switch JDKs regularly. In the morning, I could be developing a legacy system. And in the evening, I'd b writing an article on a JDK preview feature such as text blocks. And in the night, I'm working on small PR for openHAB. In today's post, I'll share some aliases that I use to easily switch JDK's on my MacBook's.

Short Introduction to 'java_home'

Luckily, macOS offers a handy tool to find information about installed JDK's, it's located in /usr/libexec/java_home and it is very usefull in setting up a JDK or running against a specific JDK. The following fragment shows the -V command which prints all the recognized JDK's:

martinvw@MacBook-Pro ~ $ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
14.0.1, x86_64: "OpenJDK 14.0.1" /Library/Java/JavaVirtualMachines/openjdk.jdk/Contents/Home
11.0.8, x86_64: "OpenJDK 11.0.8" /Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
1.8.0_171, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home

When you pass a lowercase v, you will get the path to the matching JDK:

/usr/libexec/java_home -v 11

We can also leverage the output, to update our JAVA_HOME variable and by creating some aliasses you can easily switch, see the following aliases from my .bash_aliases file:

alias j15='export JAVA_HOME=`/usr/libexec/java_home -v 15`; java -version'
alias j14='export JAVA_HOME=`/usr/libexec/java_home -v 14`; java -version'
alias j13='export JAVA_HOME=`/usr/libexec/java_home -v 13`; java -version'
alias j12='export JAVA_HOME=`/usr/libexec/java_home -v 12`; java -version'
alias j11='export JAVA_HOME=`/usr/libexec/java_home -v 11`; java -version'
alias j10='export JAVA_HOME=`/usr/libexec/java_home -v 10`; java -version'
alias j9='export JAVA_HOME=`/usr/libexec/java_home -v 9`; java -version'
alias j8='export JAVA_HOME=`/usr/libexec/java_home -v 1.8`; java -version'
alias j7='export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; java -version'

For Java 8 and older, you should prefix the version with '1.'

When switching, we'll also show the output of java -version to make it extra clear to what version we just switched. This leads us to the following output when switching:

martinvw@MacBook-Pro bash-scripts (master) $ j11
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+11)
OpenJDK 64-Bit Server VM (build 11.0.8+11, mixed mode)
Note on installing through Brew

When installing a specific JDK version via Brew it will/might not directly be visible for java_home. After installing, it will show a command you can execute to make sure it is registered properly, that will look something like the following:

==> Caveats
For the system Java wrappers to find this JDK, symlink it with
sudo ln -sfn /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk


Using java_home and some quick aliases, we can easily use multiple JDK versions in parallel and switch without any issues.