How to switch between Java LTS versions 8, 11 and 17 on Mac

Change Java version on Mac 11 BigSur & persist it is great. However, Java 17 is not included. This post includes Java LTS version 17 and shows how to switch between Java/JDK LTS versions 8, 11 and 17.

~ 2 minutes read
no time? jump straight to the javahome function

On Mac you can install Java/JVM with brew‘s openjdk formulae . That includes JAVA LTS releases 17, 11, 8:

# version 17
brew install openjdk@17
sudo ln -sfn /usr/local/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk

# version 11
brew install openjdk@11
sudo ln -sfn /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk

# version 8
brew install openjdk@8
sudo ln -sfn /usr/local/opt/openjdk@8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk

Setting the symlink after every installation step is important for the system Java wrappers to find the installed JDK. Installing JDKs with brew also recommends adding /usr/local/opt/openjdkXX/bin to PATH.

javahome function

I prefer the javahome shell function below rather than adding new values to PATH.

javahome() {
  unset JAVA_HOME 
  export JAVA_HOME=$(/usr/libexec/java_home -v "$1");
  java -version
}

alias j1.8='javahome 1.8'
alias j11='javahome 11'
alias j17='javahome 17'

Make sure to add the javahome function to your shell init file (.zshrc for me) so it is available in all terminal sessions.

javahome function in action

Now you can change the java version on the terminal using the respective alias:

$ j17
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment Homebrew (build 17.0.1+0)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.1+0, mixed mode, sharing)

$ j11
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment Homebrew (build 11.0.12+0)
OpenJDK 64-Bit Server VM Homebrew (build 11.0.12+0, mixed mode)

$ j1.8
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-bre_2021_10_20_23_15-b00)
OpenJDK 64-Bit Server VM (build 25.312-b00, mixed mode)

function javahome & aliases in action


source: https://asciinema.org/a/6BFBKsYBZckbcgXx7sPc0ePmN

source: https://youtu.be/Bck-Y5ewSbg

First version published on Miro Engineering Blog.

7 Comments

  1. I got a great comment on lnkdin from Rubén Gamarra Rodríguez:

    That is an option. On #Mac I use SDK manager https://sdkman.io/usage#listversions

    The command “sdk use java ” might be more verbose but doesn’t require maintaining a file. It doesn’t require more than a handful of command to add new JDK as they are made available. There is no need to edit a file like .zshrc and creating symlinks like it would be the case in 4 months when #Java 18 is released.

    • My reply [1,2]:

      This is great feedback – Thank you.

      The command sdk list java is great because it does list the installed java versions as well as the one in use. The sdk use java lets you choose another installed version easily.

      sdk install java 17 did not work for me, I had to specify a specific version e.g. sdk install java 17.0.1-open. SDKman supports that with tab completion though.

      The default sdkman installation command
      $ source "$HOME/.sdkman/bin/sdkman-init.sh"
      changes the bash config files. In my case these were two files both, .zshrc & .bash_profile.

      The added snippet is
      #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
      export SDKMAN_DIR="$HOME/.sdkman"
      [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh"

      and must be removed in case you want to uninstall sdkman (https://sdkman.io/install paragraph Uninstallation).

      Adding this snippet can be avoided following the https://sdkman.io/install paragraph Installing without Modifying Shell Config guide. However, I assume that’s an edge case.

      I prefer (more) explicit changes to .zshrc or similar files. Writing the changes myself is explicit enough IMO. This way I remember in case I need to troubleshoot something related or I need to uninstall packages.

      Almost all macs I observed so far have brew installed because its the missing package manager for macOS.

      I use brew regularly (e.g. osx_bootstrap.sh) because it just works for me.

      I see the point of using SDKman when you need a cli tool to easily manage multiple software development kits and its versions.

    • My reply:

      Use the aliases to set the default java version.

      You can use the snippet below in your .zshrc file (or similar):


      javahome() {
      unset JAVA_HOME
      export JAVA_HOME=$(/usr/libexec/java_home -v "$1");
      java -version
      }alias j1.8='javahome 1.8'
      alias j11='javahome 11'
      alias j17='javahome 17'j17 #this makes version 17 the default version until you change it

      This will set java version 17 when ever your .zshrc file (or similar) is executed.

      HTH

  2. Andy Bulka asks on medium:

    On my Mac (mojave 10.14.6) installing java 11 failed with a compilation error “src/jdk.hotspot.agent/macosx/native/libsaproc/symtab.c:407:71: error: too few arguments to function call, expected 5, have 4”.

    I should probably upgrade my Mac OS, I know, but having been pretty happy sitting on Mojave.

    There is also a message from brew saying: “OpenJDK is somewhat broken on newer MacOS instances, console is flooded with errors when using JMeter, AdoptOpenJDK has no issues https://github.com/Homebrew/homebrew-core/issues/66953” ?

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.