Many times, when we are compiling and building Mule apps we run into issues because we are using the wrong version of the Java JDK. The problem is that we can’t be uninstalling and installing versions of the JDK every time we’ve got an app or plugin that requires it. We need to have multiple versions of the JDK installed in our laptops and we need to find a quick way to switch between versions.
In this post, we’ll see how to do that in macOS
Installing Multiple versions of the JDK
First, install different versions of the openJDK with Homebrew:brew install openjdk@8
brew install openjdk@11
brew install openjdk@22
/usr/bin/java
, /usr/lib/jvm
& /usr/local/bin/java
. However, macOS is different, it searches for Java at/Library/Java/JavaVirtualMachines/
If we run list the directory /Library/Java/JavaVirtualMachines we can see there’s nothing in there.
And if we try:
or the java_home utility in macOS, we see that macOS is not detecting any JDK installation:
java -version
/usr/libexec/java_home -V
The Problem with Homebrew
These JDK formulae could have set up the required softlink under folder/Library/Java/JavaVirtualMachines/
. But by design, these JDK formulae are kept as keg-only.
If you noticed, during the OpenJDKs installation, this info was also provided in the logs of Homebrew:
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
openjdk@11 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.
If you need to have openjdk@11 first in your PATH, run:
echo 'export PATH="/usr/local/opt/openjdk@11/bin:$PATH"' >> ~/.zshrc
For compilers to find openjdk@11 you may need to set:
export CPPFLAGS="-I/usr/local/opt/openjdk@11/include"
The Solution
We need to do as the logs say and create soft links for each openJDK installation:
sudo ln -sfn /usr/local/opt/openjdk@8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk
sudo ln -sfn /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
Now if we have a look at /Library/Java/JavaVirtualMachines, we can see:
And using the java_home utility:
we can see three installations of the OpenJDK
Switching JDKs
Let’s see a real example in the Mule Dev day-to-day. Maven uses the JAVA_HOME env variable. If we run mvn -version
we can see the following:
We also have
/usr/libexec/
java_home
utility which we will use to move between various versions.For our installation, this is what the parameter
And double check again. We can see how we can change very quickly the OpenJDK for Maven.
-v
(small case v) gives us.We can leverage the output of this command to set JAVA_HOME as below,
After that, if we check again with Maven:
export JAVA_HOME=`/usr/libexec/java_home -v 11`
The command is too long, so we can use some alias
Now we just need to type java-11, java-8 or java—2 to switch between versions.
alias java-22="export JAVA_HOME=`/usr/libexec/java_home -v 22`"
alias java-11="export JAVA_HOME=`/usr/libexec/java_home -v 11`"
alias java-8="export JAVA_HOME=`/usr/libexec/java_home -v 1.8`"
And double check again. We can see how we can change very quickly the OpenJDK for Maven.
Lastly, to make these aliases permanent and available every time we open a new terminal we will add them to the ~/.zshrc file