Main Tutorials

How to install Java JDK on macOS

This article shows how to install Java JDK on macOS, Homebrew package manager, manual installation, and switch between different JDK versions.

Tested with

  • macOS 11 Big Sur
  • Homebrew 2.7.4
  • JDK 8, 14, 16, 16 (AdoptOpenJDK and OpenJDK)

Topics

  1. Homebrew install latest Java (OpenJDK) on macOS
  2. Homebrew install Java 8 (OpenJDK) on macOS
  3. Homebrew install a specified Java (AdoptOpenJDK) on macOS
  4. Manual install Java (Early-Access Builds) on macOS
  5. Switch between different JDK versions

P.S At the time of writing, the latest JDK GA is JDK 15, and the early access build is JDK 16.

Note
Since macOS 10.15 Catalina, the default Terminal shell switch from the bash (Bourne-again shell) to zsh (Z shell). And we should move all the startup scripts and environment variables in ~/.bash_profile or ~/.bashrc to ~/.zshenv or ~/.zshrc.

Also, read this Zsh Startup Files.

1. Homebrew install latest Java on macOS

1.1 Install and upgrade Homebrew.

1.2 brew search java to find all available Java-related formula.

Terminal

% brew search java      

==> Formulae
app-engine-java           java                      javacc                    jslint4java               pdftk-java
google-java-format        java11                    javarepl                  libreadline-java

1.3 brew info to show the formula details.

The java formula is always containing the latest Java JDK (OpenJDK) GA version; at the time of writing, the latest GA is JDK 15.

Terminal

% brew info java

openjdk: stable 15.0.1 (bottled) [keg-only]
Development kit for the Java programming language
https://openjdk.java.net/
/usr/local/Cellar/openjdk/15.0.1 (614 files, 324.9MB)
  Poured from bottle on 2020-12-09 at 09:06:07
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openjdk.rb
License: Cannot Represent

The java11 formula is containing the Java 11 LTS version.

Terminal

% brew info java11  

openjdk@11: stable 11.0.9 (bottled) [keg-only]
Development kit for the Java programming language
https://openjdk.java.net/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/[email protected]
License: GPL-2.0-only

1.4 brew install java to install the latest JDK 15.

Terminal

% brew info java

1.5 Where does Homebrew install the java?
Homebrew installed the JDK files and directories at /usr/local/Cellar/openjdk/, and symbolic link at /usr/local/opt/openjdk points to the latest Java 15.0.1 version.

Terminal

% ls -lsa /usr/local/Cellar/openjdk/      

total 0
0 drwxr-xr-x   3 mkyong  staff    96 Dec  9 09:06 .
0 drwxrwxr-x  69 mkyong  admin  2208 Jan 15 15:35 ..
0 drwxr-xr-x   9 mkyong  staff   288 Jan 15 16:47 15.0.1

% ls -lsa /usr/local/opt/openjdk
0 lrwxr-xr-x  1 mkyong  admin  24 Dec  9 09:06 /usr/local/opt/openjdk -> ../Cellar/openjdk/15.0.1

1.6 The java formula is keg-only, which means it is installed in /usr/local/Cellar but not linked into places like /usr/local/bin or /Library/Java/JavaVirtualMachines/ (macOS /usr/bin/java wrapper).

For macOS /usr/bin/java wrapper to find the installed JDK, we manually create a symbolic link at /Library/Java/JavaVirtualMachines/.

Terminal

% sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk

1.7 Done.

Terminal

% java -version

openjdk version "15.0.1" 2020-10-20
OpenJDK Runtime Environment (build 15.0.1+9)
OpenJDK 64-Bit Server VM (build 15.0.1+9, mixed mode, sharing)

2. Homebrew install Java 8 on macOS

2.1 Install and upgrade Homebrew.

2.2 The brew search java has no java8?

Terminal

% brew search java        
==> Formulae
app-engine-java           java                      javacc                    jslint4java               pdftk-java
google-java-format        java11                    javarepl                  libreadline-java

2.3 The Java 8 is available at the openjdk@8 formula. The openjdk is the same as the java formula, and it always contains the latest JDK GA version; the openjdk@11 is the same as the java11 formula, containing JDK 11.

Terminal

% brew search openjdk
==> Formulae
openjdk                                   openjdk@11                                  openjdk@8  

2.4 We can use the openjdk@8 formula to install Java 8 on macOS.

Terminal

% brew install openjdk@8

2.5 The openjdk@8 is also a keg-only; we need to create a symbolic link so that the macOS java wrapper can find it.

Terminal

% sudo ln -sfn /usr/local/opt/openjdk@8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk  

2.6 Done.

Terminal

% java -version

openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-bre_2020_11_16_15_09-b00)
OpenJDK 64-Bit Server VM (build 25.275-b00, mixed mode)

2.7 What if we have multiple Java versions installed?

Terminal

ls -lsah /Library/Java/JavaVirtualMachines/               

openjdk-8.jdk -> /usr/local/opt/openjdk@8/libexec/openjdk.jdk
openjdk.jdk -> /usr/local/opt/openjdk/libexec/openjdk.jdk

We can update the $PATH at ~/.zshrc, so that the macOS can find the correct installed Java.

Terminal

% java -version

openjdk version "15.0.1" 2020-10-20
OpenJDK Runtime Environment (build 15.0.1+9)
OpenJDK 64-Bit Server VM (build 15.0.1+9, mixed mode, sharing)

% echo 'export PATH="/usr/local/opt/openjdk@8/bin:$PATH"' >> ~/.zshrc  

% source ~/.zshrc

% java -version

openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-bre_2020_11_16_15_09-b00)
OpenJDK 64-Bit Server VM (build 25.275-b00, mixed mode)

$JAVA_HOME
Alternatively, we can set the $JAVA_HOME environment variable on macOS.

3. Homebrew install a specified Java (AdoptOpenJDK) on macOS.

The adoptopenjdk/openjdk tap containing a lot of different JDK (AdoptOpenJDK) versions.

3.1 Add a new tap (third party repository) adoptopenjdk/openjdk.

Terminal

% brew tap adoptopenjdk/openjdk

3.2 Search related adoptopenjdk formula.

Terminal

% brew search adoptopenjdk

==> Casks
adoptopenjdk                              adoptopenjdk12-openj9                     adoptopenjdk14-openj9-large
adoptopenjdk-jre                          adoptopenjdk12-openj9-jre                 adoptopenjdk15
adoptopenjdk-openj9                       adoptopenjdk12-openj9-jre-large           adoptopenjdk15-jre
adoptopenjdk-openj9-jre                   adoptopenjdk12-openj9-large               adoptopenjdk15-openj9
adoptopenjdk-openj9-jre-large             adoptopenjdk13                            adoptopenjdk15-openj9-jre
adoptopenjdk-openj9-large                 adoptopenjdk13-jre                        adoptopenjdk15-openj9-jre-large
adoptopenjdk10                            adoptopenjdk13-openj9                     adoptopenjdk15-openj9-large
adoptopenjdk11                            adoptopenjdk13-openj9-jre                 adoptopenjdk8
adoptopenjdk11-jre                        adoptopenjdk13-openj9-jre-large           adoptopenjdk8
adoptopenjdk11-openj9                     adoptopenjdk13-openj9-large               adoptopenjdk8-jre
adoptopenjdk11-openj9-jre                 adoptopenjdk14                            adoptopenjdk8-openj9
adoptopenjdk11-openj9-jre-large           adoptopenjdk14-jre                        adoptopenjdk8-openj9-jre
adoptopenjdk11-openj9-large               adoptopenjdk14-openj9                     adoptopenjdk8-openj9-jre-large
adoptopenjdk12                            adoptopenjdk14-openj9-jre                 adoptopenjdk8-openj9-large
adoptopenjdk12-jre                        adoptopenjdk14-openj9-jre-large           adoptopenjdk9

3.3 We pick adoptopenjdk14 formula to install the JDK 14.

Terminal

% brew install adoptopenjdk14

installer: Package name is AdoptOpenJDK
installer: Installing at base path /
installer: The install was successful.
package-id: net.adoptopenjdk.14.jdk
version: 14.0.2+12
volume: /
location: Library/Java/JavaVirtualMachines/adoptopenjdk-14.jdk
install-time: 1610720586
adoptopenjdk14 was successfully installed!

3.4 The adoptopenjdk formula creates the JDK home directly in the /Library/Java/JavaVirtualMachines/.

Terminal

% ls -lsa /Library/Java/JavaVirtualMachines/

adoptopenjdk-14.jdk
openjdk-8.jdk -> /usr/local/opt/openjdk@8/libexec/openjdk.jdk
openjdk.jdk -> /usr/local/opt/openjdk/libexec/openjdk.jdk

3.5 Since the JDK home is already in /Library/Java/JavaVirtualMachines/, we do not need to create any symbolic link, just export $PATH and point it to the correct adoptopenjdk-14.jdk.

Terminal

% echo 'export PATH="/Library/Java/JavaVirtualMachines/adoptopenjdk-14.jdk/Contents/Home/bin:$PATH"' >> ~/.zshrc

% source ~/.zshrc

% java -version
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)

4. Manual install Java (Early-Access Builds) on macOS.

For some reasons, we need to install Java on macOS manually:

  • Anti-Homebrew, developers love to control everything.
  • The JDK build doesn’t exist in the Homebrew repository, like the early-access builds, or Oracle JDK.

P.S At the time of writing, the JDK early-access build is JDK 16.

4.1 Access the JDK 16 early access build website and download the JDK.

install jdk16 on macOS

4.2 Extracts the downloaded tar.gz file to /Library/Java/JavaVirtualMachines

Terminal

% sudo tar xvzf ~/Downloads/openjdk-16-ea+32_osx-x64_bin.tar.gz -C /Library/Java/JavaVirtualMachines

% ls -lsa /Library/Java/JavaVirtualMachines

adoptopenjdk-14.jdk
jdk-16.jdk
openjdk-8.jdk -> /usr/local/opt/openjdk@8/libexec/openjdk.jdk
openjdk.jdk -> /usr/local/opt/openjdk/libexec/openjdk.jdk

4.3 Update $PATH and point to the /Library/Java/JavaVirtualMachines/jdk-16.jdk

Terminal

% echo 'export PATH="/Library/Java/JavaVirtualMachines/jdk-16.jdk/Contents/Home/bin:$PATH"' >> ~/.zshrc

4.4 Test JDK 16.

Terminal

% source ~/.zshrc

% java -version
openjdk version "16-ea" 2021-03-16
OpenJDK Runtime Environment (build 16-ea+32-2190)
OpenJDK 64-Bit Server VM (build 16-ea+32-2190, mixed mode, sharing)

Done.

5. Switch between different JDK versions

From the above example 1 to example 4, we have installed four JDK versions on macOS.

5.1 List all the JDK versions on macOS.

Terminal

% /usr/libexec/java_home -V

Matching Java Virtual Machines (4):
  16 (x86_64) "Oracle Corporation" - "OpenJDK 16-ea" /Library/Java/JavaVirtualMachines/jdk-16.jdk/Contents/Home
  15.0.1 (x86_64) "UNDEFINED" - "OpenJDK 15.0.1" /usr/local/Cellar/openjdk/15.0.1/libexec/openjdk.jdk/Contents/Home
  14.0.2 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 14" /Library/Java/JavaVirtualMachines/adoptopenjdk-14.jdk/Contents/Home
  1.8.0_275 (x86_64) "UNDEFINED" - "OpenJDK 8" /usr/local/Cellar/openjdk@8/1.8.0+275/libexec/openjdk.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/jdk-16.jdk/Contents/Home

% ls -lsa /Library/Java/JavaVirtualMachines

adoptopenjdk-14.jdk
jdk-16.jdk
openjdk-8.jdk -> /usr/local/opt/openjdk@8/libexec/openjdk.jdk
openjdk.jdk -> /usr/local/opt/openjdk/libexec/openjdk.jdk

5.2 Add the below function in the ~/.zshrc (for macOS 10.15 Catalina, and above) or ~/.bashrc (before macOS 10.15 Catalina).

~/.zshrc

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

P.S Create the file ~/.zshrc if it doesn’t exists.

5.3 Source the ~/.zshrc to reflect the changes.

Terminal

% source ~/.zshrc

5.4 Switch between different JDK versions.

Terminal

% java -version
openjdk version "16-ea" 2021-03-16
OpenJDK Runtime Environment (build 16-ea+32-2190)
OpenJDK 64-Bit Server VM (build 16-ea+32-2190, mixed mode, sharing)

% jdk 1.8
openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-bre_2020_11_16_15_09-b00)
OpenJDK 64-Bit Server VM (build 25.275-b00, mixed mode)

% jdk 14
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)

% jdk 15
openjdk version "15.0.1" 2020-10-20
OpenJDK Runtime Environment (build 15.0.1+9)
OpenJDK 64-Bit Server VM (build 15.0.1+9, mixed mode, sharing)

% jdk 16
openjdk version "16-ea" 2021-03-16
OpenJDK Runtime Environment (build 16-ea+32-2190)
OpenJDK 64-Bit Server VM (build 16-ea+32-2190, mixed mode, sharing)

Further Reading
How to set $JAVA_HOME environment variable on macOS.

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
36 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Jim
1 year ago
/usr/local/opt

doesn’t exist on macOS Monterey.

bharadwaj
3 years ago

This is awesome!! Thankyou.

Viraj Bhosle
1 year ago

Somehow jvisualvm doesn’t work with these steps. “Unable to locate a Java Runtime that supports jvisualvm.”

Chris
2 years ago

Microsoft has also released a OpenJDK version for Linux, MacOS and Windows.

Link https://docs.microsoft.com/fr-fr/java/openjdk/download

xpt
3 years ago
$ ls -lsa /Library/Java/JavaVirtualMachines
ls: cannot read symbolic link '/Library/Java/JavaVirtualMachines/openjdk.jdk': Permission denied
total 0
0 drwxr-xr-x 4 root wheel 128 2021-03-05 13:04 .
0 drwxr-xr-x 4 root wheel 128 2020-09-21 17:17 ..
0 drwxr-xr-x 3 root wheel 96 2021-01-18 17:29 jdk1.8.0_261.jdk
0 lrwxr-x--x 1 root wheel 42 2021-03-05 13:04 openjdk.jdk

Why I got that?

Besides, I’m getting

$ groovy -v
Error occurred during initialization of VM
Unable to load jimage library: /usr/local/Cellar/openjdk/15.0.1/libexec/openjdk.jdk/Contents/Home/lib/libjimage.dylib

How to fix it?

Greg
3 years ago

you are my hero

Ben
3 years ago

Lovely, thanks!

Arpan Chakraborty
3 years ago

How do i switch from openjdk version “11.0.2” to openjdk version “11.0.7”

jman
4 years ago

I guess the best method for a Linux/MacOS machine to install Java + other goodies and to switch to different versions, is to use sdkman (https://sdkman.io/).

Anatoliy
3 years ago
Reply to  jman

I fully support! Entering this article, I expected to see it sdkman!

FrancoVega
1 year ago

Thank you, it worked well!!!

dildev
1 year ago

I want to install specific minor version in java 8. How do I do that?

absalón
1 year ago

great!!

Jyoti
1 year ago

Hi i have three java version in my mac but m not able to switch between them
pls help

Amanda
2 years ago

Thanks for this

Mona
2 years ago

Thank You. Explained so well

Alexander
2 years ago

Very helpful

A J
2 years ago

This is awesome, thanks

Deepak
2 years ago

Thanks for tutorial. It helped me

ansari
2 years ago

thank you , it was helpful

Nikolas
2 years ago

#JDK control
java-jdk() {
  version=$1
  case $version in
    “”) /usr/libexec/java_home -V;;
    *) export JAVA_HOME=$(/usr/libexec/java_home -v $version);java -version;;
  esac
}

Yolanda
2 years ago

Thank you! It helps me a lot.

In 1.4, “% brew info java” is this typo of “% brew install java” ?

devjunior
2 years ago

Nice one! Saved my day!

banu
2 years ago

Thank you!!

Ben Hutchison
3 years ago

Thank you mkyong, great guidance. Have made a charity donation to Wikimedia to repay (and also because I use it all the time and really should!) 😛

Jason Hendriks
3 years ago

1. Newer MacOS versions report java_home as:
% /usr/libexec/java_home 
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home

This is not useful. You need to point JAVA_HOME to the binary in /Library/Java/JavaVirtualMachines.

2. bash is no longer the default shell, it’s zsh. You have to set JAVA_HOME in ~/.zprofile

kate
3 years ago

thank you so much. brew didn’t work few days ago.. but it work now! your post is very helpful

Rushi Doshi
3 years ago

Thank you sooooo much. It helped me a lot. God bless you. Keep up the good work.

Luis
3 years ago

Very useful
If you have problems with brew because AdoptOpenJDKXX is present in both casks, use
“brew cask install adoptopenjdk/openjdk/adoptopenjdkXX”

Michael
1 year ago

Whenever I have a Java related question, I always come back here first. Thank you!

Pranav
1 year ago

Thank you. Crisp and to the point.