On macOS you can use /usr/libexec/java_home command to control your used Java version. As a lot of applications and/or projects still require Java 1.8 or you might want to use an alternative JDK/JRE let’s look into managing those different versions.

$ /usr/libexec/java_home -h
Usage: java_home [options...]
    Returns the path to a Java home directory from the current user's settings.

Options:
    [-v/--version   <version>]       Filter Java versions in the "JVMVersion" form 1.X(+ or *).
    [-a/--arch      <architecture>]  Filter JVMs matching architecture (i386, x86_64, etc).
    [-d/--datamodel <datamodel>]     Filter JVMs capable of -d32 or -d64
    [-t/--task      <task>]          Use the JVM list for a specific task (Applets, WebStart, BundledApp, JNI, or CommandLine)
    [-F/--failfast]                  Fail when filters return no JVMs, do not continue with default.
    [   --exec      <command> ...]   Execute the $JAVA_HOME/bin/<command> with the remaining arguments.
    [-R/--request]                   Request installation of a Java Runtime if not installed.
    [-X/--xml]                       Print full JVM list and additional data as XML plist.
    [-V/--verbose]                   Print full JVM list with architectures.
    [-h/--help]                      This usage information.

Manual installation

For this post I’ve decided to use AdoptOpenJDK as it’s actively maintained.

  1. Download the installation package.

  2. Launch a Terminal

  3. Run the following command:

    $ sudo installer -pkg ~/Downloads/OpenJDK11U-jdk_x64_mac_hotspot_11.0.6_10.pkg -target /
    Password: *****
    ...
    
  4. Enter the Administrator password.

  5. AdoptOpenJDK installs to /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk

  6. After installation you can run /usr/libexec/java_home -V to list your installed JDKs:

    $ /usr/libexec/java_home -V
    Matching Java Virtual Machines (1):
         11.0.6, x86_64: "AdoptOpenJDK 11"    /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
    
  7. Setting a static JAVA_HOME may be dangerous, after updating Java path is usually different. By adding following line to your .profile file or .zshrc (if you’re using zsh) will still work after this update.

    export JAVA_HOME=$(/usr/libexec/java_home -v 11)
    

SDKMan

Install SDKMan according to their very good online installation tutorial. After you’ve completed the installation you can install AdoptOpenJDK using sdk command.

  1. Launch a Terminal

  2. Install SDKMan as documented on the website

  3. Run the following command:

    $ sdk list java
    ...
    adoptopenjdk-11.0.6.hs-adpt
    ...
    
  4. Select the version you want to install - we use the same as above with manual install - and run the command:

    $ sdk install java 11.0.6.hs-adpt
    ...
    
  5. Use following command to set JAVA_HOME:

    sdk use java 11.0.6.hs-adpt
    

To set the default Java version you can run:

sdk default java 11.0.6.hs-adpt

asdf

Main goal of asdf is to manage multiple runtime versions with a single CLI tool - btw also SDKMan is targeting the same.

Using a plugin system for runtimes asdf is very extensible by the community.

  1. Install asdf as documented on the website or by running brew install asdf on macOS.

  2. Launch a Terminal

  3. Run the following commands:

    $ asdf plugin add java
    $ asdf list all java
    adopt-openjdk-10.0.2+13.1
    adopt-openjdk-11+28
    ...
    adopt-openjdk-11.0.6+10
    ...
    adopt-openjdk-8u242-b08
    ....
    amazon-corretto-8.242.08.1
    ...
    azul-zulufx-8.44.0.13-jdk8.0.242
    ...
    
  4. Select the version you want to install - we use the same as above with manual and sdkman install - and run the command:

    $ asdf install java adopt-openjdk-11.0.6+10
    ...
    OpenJDK11U-jdk_x64_mac_hotspot_11.0.6_10.tar.gz.sha256.txt
    OpenJDK11U-jdk_x64_mac_hotspot_11.0.6_10.tar.gz: OK
    
  5. Unfortunately asdf does not set JAVA_HOME automatically, but it adjusts the PATH to point to correct Java version if you execute:

    $ asdf shell java adopt-openjdk-11.0.6+10
    $ env|grep -i java
    ASDF_JAVA_VERSION=adopt-openjdk-11.0.6+10
    $ which java
    /Users/daniel/.asdf/shims/java
    
  6. If you want to set JAVA_HOME, please the following command, variable ASDF_JAVA_VERSION can be any Java version you have installed (it was set to adopt-openjdk-11.0.6+10 in this example by asdf shell java adopt-openjdk-11.0.6+10 command):

    $ export JAVA_HOME=$(asdf where java $ASDF_JAVA_VERSION)
    $ env|grep -i java
    ASDF_JAVA_VERSION=adopt-openjdk-11.0.6+10
    JAVA_HOME=/Users/daniel/.asdf/installs/java/adopt-openjdk-11.0.6+10
    

Conclusion

I’ve fully changed my Workstation to asdf and removed SDKMan, pyenv, nvm, etc. asdf is the most flexible runtime manager and keeps all runtimes installed in user profile.

asdf also supports per project configuration via a .tool-versions file or setting the ASDF_<tool>_VERSION environment variable.