Installing & switching between multiple JDK on macOS

Manvendra P Singh
5 min readMar 2, 2022

--

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 to 17.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

  1. It installs the package into the package's own directory
    Under /opt/homebrew/Cellar for M1-Mac
    Under /usr/local/Cellar for Intel Mac
  2. 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

From Homebrew website

This information is also present in our install logs.

See highlighted text for Keg-only statement

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 and openjdk
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"

--

--