Installing & switching between multiple JDK on macOS
None of the operating systems comes with a preinstalled JDK, including macOS. In this post, let's see how to manually install and manage multiple JDK on macOS.
If you are not interested in any explanation, go to the very end of the post for commands. But I’ll recommend reading it.
A well-known process for installing any software on macOS is, either clicking an app icon or drag-and-drop the app icon into the Applications folder. This hides all installation details under the fancy app icons and an in-progress bar.
However, we developers like to see the logs and play with the command line tools. For this purpose, Linux Distros
use package managers like yum
or apt-get
. But as with all things Apple, Most common free software don't work in macOS. This is where HomeBrew
comes to the rescue
HomeBrew
As the tool's homepage says, it is
The Missing Package Manager for macOS.
Homebrew is the easiest and most flexible way to install the UNIX tools Apple didn’t include with macOS.
With homebrew, we can install the software via the command line and can see a lot of installation information in the logs.
Installing Homebrew
To install Homebrew
on macOS, Open either Terminal
or iTerm
application in macOS and run the below command.
/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
After this completes, we can use homebrew to install available formulae
or cask
with just one line commands brew install xxxx
or brew install --cask xxxx
Installing various JDK versions
First, let's search Homebrew
to find available java versions. Use the following command.
brew search --formulae java.
As you can see below, only java11
and java
are available.
Formulae name with no version prefix resolves to the Current GA version, at the time of writing this post,
java
formulae resolves to17.0.2
If you want older versions, you can search with formulae openjdk
.java
and java11
are just alias for openjdk
and openjdk@11
Now we know the formulae name, we can install different JDKs by one single command. Let's install current versions and java11.
Run the following 2 commands one after another, in Terminal
or iTerm
brew install openjdk
brew install openjdk@11
Some manual settings
Now java 17 and java 11 both are installed on our mac.
Let’s see which one will be used by Mac Programs.
- On any machine, the easiest way to check the current java version is by
java -version
- You can also check all installed java versions on macOS by
java_home /usr/libexec/java_home -V
However, When I try the above 2 commands, I get this output
Somehow, macOS is not able to detect the java installed by Homebrew.
This is because whenever you install a package with Homebrew
- It installs the package into the package's own directory
Under/opt/homebrew/Cellar
for M1-Mac
Under/usr/local/Cellar
for Intel Mac - It also creates a soft-link under
/opt/homebrew/opt
But *nix systems search for java under /usr/bin/java
, /usr/lib/jvm
& /usr/local/bin/java
. As with all things Apple, macOS is different, it searches for Java at /Library/Java/JavaVirtualMachines/
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
This information is also present in our install logs.
So we need to create a few soft links in the mentioned folder if we want installed Java to be detected by all the Mac programs. Copy-paste the command given in install logs as is
Now if we try to run the failing command at the start of this section we see below the output
Now that we have 2 JDKs installed and detected by macOS, let's see how to quickly switch between the two.
If you are installing only one version of Java we are done. But, if you want many different versions of java on your Mac, you can install each of them as per the steps above & switch between them as per the steps below
Switching JDKs (JAVA_HOME & java_home)
JAVA_HOME
is the environment variable that directs java programs to pick the Java location. So to switch between various java versions we need to change the JAVA_HOME value to different locations
We also have /usr/libexec/java_home
utility which we will use to move between various versions.
For our installation, this is what parameter -v
(small case v) gives us
- We can leverage the output of this command to set JAVA_HOME as below,
export JAVA_HOME=`/usr/libexec/java_home -v 17
- But the command might be a little long to type, So let's create a one-word alias to replace the whole command.
alias java-17=”export JAVA_HOME=`/usr/libexec/java_home -v 17`”
- We also need to make sure, every time we open a new terminal, these aliases are available. For that, we need to add them in
~/.zshrc
file. Add following 2 aliases in~/.zshrc
file. Create~/.zshrc
if it doesn’t exist.
alias java-17=”export JAVA_HOME=`/usr/libexec/java_home -v 17`; java -version”
alias java-11=”export JAVA_HOME=`/usr/libexec/java_home -v 11`; java -version”
We are all done.
Just type java-11
or java-17
on your Terminal
or iTerm
whenever you want to change the java versions.
TL;DR (Quick summary of command)
For all those who just want the steps, not any explanation, here are the quick steps.
- Install Homebrew if you do not have on your system
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- Install as many JDK as you want with
Homebrew
andopenjdk
brew install openjdk@XX
- Make JDK accessible for MAC, by adding either a soft link or real folders in
/Library/Java/JavaVirtualMachines/
. For Softline use below command
sudo ln -sfn /opt/homebrew/opt/openjdkXXX/libexec/openjdkXXX.jdk /Library/Java/JavaVirtualMachines/openjdkXXX.jdk
- Add one more alias under
~/.zshrc
to quickly switch between JDK
alias java-XX="export JAVA_HOME=`/usr/libexec/java_home -v XX`; java -version"