Keywords: Java, JDK (Java Development Kit), MacOS, Homebrew, Specific Version
This how-to guide covers how to install different versions of the JDK on MacOS with Homebrew.
This guide favors OpenJDK.
This guide favors free, simple, and permissive licensing whenever possible, so we will favor OpenJDK first, then AdoptOpenJDK if plain OpenJDK isn't available, any other open source distributions, and finally Oracle JDK if no other options are available. We favor OpenJDK because it has a permissive license, the GPL v2 with Classpath Exception (aka linking exception). For more information, see Oracle now requires a subscription to use Java SE (2018).
- For Java 8 and later, OpenJDK is readily available.
- For versions prior to Java 8 or other special circumstances, OpenJDK may not be available. We will cover how to install whatever is most readily available.
Note that this guide contains plenty of CLI command outputs. The intent of including these outputs is to illustrate what output should look like. Our goal IS NOT to keep up with exactly what the output is at the present day. This guide DOES NOT guarantee or even attempt to keep all those command outputs updated with the ever-evolving Hombrew formulae changes.
What's important are the commands, and the general form of the outputs. This guide WILL attempt to keep up-to-date with the best commands to run.
Just be aware that if something's been working for a while, the command output might look old, but the command itself will probably still run fine for more recent updates.
Install Homebrew.
Remember to frequently brew update
. Homebrew may also auto-update upon running key homebrew commands such as install
or upgrade
.
$ brew update
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
==> Updated Casks
foo
Double check your registered taps by running brew tap
. It's generally good practice to have homebrew/cask
and homebrew/cask-versions
taprooms tapped, especially when installing multiple Java versions.
Check your taps.
$ brew tap
homebrew/cask
homebrew/cask-versions
homebrew/core
homebrew/services
If homebrew/cask
and homebrew/cask-versions
aren't in the list of your registered taps, then run brew tap homebrew/cask
and brew tap homebrew/cask-versions
to tap them.
Tap into the cask
caskroom.
$ brew tap homebrew/cask
==> Tapping homebrew/cask
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask'...
remote: Enumerating objects: 72, done.
remote: Counting objects: 100% (72/72), done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 491774 (delta 34), reused 29 (delta 14), pack-reused 491702
Receiving objects: 100% (491774/491774), 226.08 MiB | 25.32 MiB/s, done.
Resolving deltas: 100% (348965/348965), done.
Tapped 1 command and 3713 casks (3,831 files, 242MB).
Tap into the cask-versions
caskroom.
$ brew tap homebrew/cask-versions
==> Tapping homebrew/cask-versions
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask-versions'...
remote: Enumerating objects: 34, done.
remote: Counting objects: 100% (34/34), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 230190 (delta 17), reused 6 (delta 6), pack-reused 230156
Receiving objects: 100% (230190/230190), 59.24 MiB | 7.37 MiB/s, done.
Resolving deltas: 100% (158472/158472), done.
Tapped 166 casks (213 files, 65.6MB).
A lot of the information in this how-to guide is simply gathered from brew search
and brew info
. If you're still getting the hang of things, I highly recommend you run these commands yourself to get an overview of what's available and learn how to search Homebrew's formulae.
Java/JDK formula/cask names typically contain either java
or jdk
. Let's brew search
for java
and jdk
to see potential formulas.
$ brew search java
==> Formulae
app-engine-java java11 ✔ jslint4java
google-java-format javacc libreadline-java
java ✔ javarepl pdftk-java
==> Casks
charles-applejava eclipse-javascript java6 netbeans-java-se
eclipse-java java-beta netbeans-java-ee oracle-jdk-javadoc
If you meant "java" specifically:
It was migrated from homebrew/cask to homebrew/core.
We can see some of the formulae/casks we're looking for, such as java
, java11
, or java-beta
.
$ brew search jdk
==> Formulae
openjdk ✔ openjdk@11 ✔ openjdk@8 ✔
==> Casks
adoptopenjdk jdk-mission-control oracle-jdk-javadoc
adoptopenjdk8 oracle-jdk sapmachine-jdk
We can see some more potential formulae/casks we're looking for, such as openjdk
, adoptopenjdk8
, and oracle-jdk
.
Get the summary and metadata for a formula/cask you are interested in by running brew info <formula>
or brew cask info <cask>
.
As an example, let's start simple and get the info of java
. java
is an alias for the openjdk
formula. At the time of writing, the current version is OpenJDK 15.
$ brew info java
Warning: Treating java as a formula.
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, 323.8MB)
Poured from bottle on 2020-11-05 at 14:06:55
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openjdk.rb
License: Cannot Represent
==> Dependencies
Build: autoconf ✔
==> Caveats
For the system Java wrappers to find this JDK, symlink it with
sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
openjdk is keg-only, which means it was not symlinked into /usr/local,
because it shadows the macOS `java` wrapper.
If you need to have openjdk first in your PATH run:
echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc
For compilers to find openjdk you may need to set:
export CPPFLAGS="-I/usr/local/opt/openjdk/include"
==> Analytics
install: 181,357 (30 days), 434,315 (90 days), 1,183,511 (365 days)
install-on-request: 71,666 (30 days), 175,260 (90 days), 260,903 (365 days)
build-error: 0 (30 days)
The java-beta
cask contains the OpenJDK Early Access JDK.
homebrew/cask-versions
must be tapped.
Double check information about the cask, such as JDK build version and OpenJDK.
$ brew cask info java-beta
java-beta: 16,25
https://jdk.java.net/
/usr/local/Caskroom/java-beta/16,25 (144B)
From: https://github.com/Homebrew/homebrew-cask-versions/blob/HEAD/Casks/java-beta.rb
==> Name
OpenJDK Early Access Java Development Kit
==> Description
Early access development kit for the Java programming language
==> Artifacts
jdk-16.jdk -> /Library/Java/JavaVirtualMachines/openjdk-16.jdk (Generic Artifact)
Install the early access feature release of the OpenJDK.
$ brew cask install java-beta
==> Downloading https://download.java.net/java/early_access/jdk16/25/GPL/openjdk
Already downloaded: /Users/georgep/Library/Caches/Homebrew/downloads/ce9292709109d07c9bd145508e429bcb4a446bf13f2e6828e66a253b3ad8cb71--openjdk-16-ea 25_osx-x64_bin.tar.gz
==> Verifying SHA-256 checksum for Cask 'java-beta'.
==> Installing Cask java-beta
==> Moving Generic Artifact 'jdk-16.jdk' to '/Library/Java/JavaVirtualMachines/openjdk-16.jdk'
🍺 java-beta was successfully installed!
- The
openjdk
is a formula avilable onhomebrew/core
. You don't have to tap any additional taprooms/caskrooms. - There is a
java
alias which points toopenjdk
, if you prefer the alias.
Double check information about the formula, such as JDK version and OpenJDK being the source.
$ brew info openjdk
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, 323.8MB)
Poured from bottle on 2020-11-05 at 14:06:55
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openjdk.rb
License: Cannot Represent
==> Dependencies
Build: autoconf ✔
==> Caveats
For the system Java wrappers to find this JDK, symlink it with
sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
openjdk is keg-only, which means it was not symlinked into /usr/local,
because it shadows the macOS `java` wrapper.
If you need to have openjdk first in your PATH run:
echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc
For compilers to find openjdk you may need to set:
export CPPFLAGS="-I/usr/local/opt/openjdk/include"
==> Analytics
install: 181,357 (30 days), 434,315 (90 days), 1,183,511 (365 days)
install-on-request: 71,666 (30 days), 175,260 (90 days), 260,903 (365 days)
build-error: 0 (30 days)
Install the most recent stable feature release of OpenJDK
$ brew install openjdk
NOTE: Pay attention to the caveat about manually symlinking the jdk into /Library/Java/JavaVirtualMachines
. It's a manual "opt-in" to treating the Java installation as recognizable by the system at large. It's recommended you run the provided symlink command.
JDK 11 is an LTS (Long Term Support) version.
- There is no such thing as a
java-lts
formula or cask, because there is no single LTS version. You must explicitly choose to install Java 11. - Note that this formula is available on
homebrew/core
, so you don't need to have tapped any caskrooms. - There is a
java11
alias which points toopenjdk@11
.
$ brew info openjdk@11 # Confirm information about the formula. Note that it's poured from the OpenJDK formula.
$ brew install openjdk@11 # Install OpenJDK 11
Homebrew does not offer an obvious way to install an older feature release of Java other than the current generally-available feature release. For example, there is no such formula as openjdk@14
or java14
in homebrew/core
, nor is there such a cask in homebrew/cask
or homebrew-cask-versions
.
There is good reason for this; out-of-date feature releases are explicitly not supported by OpenJDK. Only the current feature release is supported (thus we get formulae with continual version updates like openjdk
). Quoting jdk.java.net - JDK 14 Releases:
JDK 14 has been superseded. Please visit jdk.java.net for the current version.
Older releases, which do not include the most up to date security vulnerability fixes and are no longer recommended for use in production, remain available in the OpenJDK Archive.
If you still need to install an Older JDK Feature Release, here are some recommendations.
-
Manually download and install your desired version from the OpenJDK Archive.
-
Use SDKMAN to install either OpenJDK or AdoptOpenJDK versions. See SDKMAN for more info.
➜ ~ sdk list java ================================================================================ Available Java Versions ================================================================================ Vendor | Use | Version | Dist | Status | Identifier -------------------------------------------------------------------------------- AdoptOpenJDK | | 15.0.1.j9 | adpt | | 15.0.1.j9-adpt | | 15.0.1.hs | adpt | | 15.0.1.hs-adpt | | 14.0.2.j9 | adpt | | 14.0.2.j9-adpt | | 14.0.2.hs | adpt | | 14.0.2.hs-adpt | | 13.0.2.j9 | adpt | | 13.0.2.j9-adpt | | 13.0.2.hs | adpt | | 13.0.2.hs-adpt | | 12.0.2.j9 | adpt | | 12.0.2.j9-adpt | | 12.0.2.hs | adpt | | 12.0.2.hs-adpt | | 11.0.9.j9 | adpt | | 11.0.9.j9-adpt | | 11.0.9.hs | adpt | | 11.0.9.hs-adpt | | 8.0.275.j9 | adpt | | 8.0.275.j9-adpt | | 8.0.275.hs | adpt | | 8.0.275.hs-adpt | | 8.0.272.hs | adpt | | 8.0.272.hs-adpt ... Java.net | | 16.ea.24 | open | | 16.ea.24-open | | 16.ea.7.lm | open | | 16.ea.7.lm-open | | 16.ea.2.pma | open | | 16.ea.2.pma-open | | 15.0.1 | open | | 15.0.1-open | | 14.0.2 | open | | 14.0.2-open | | 14.0.1 | open | local only | 14.0.1-open | | 13.0.2 | open | | 13.0.2-open | | 12.0.2 | open | | 12.0.2-open | >>> | 11.0.2 | open | installed | 11.0.2-open | | 10.0.2 | open | | 10.0.2-open | | 9.0.4 | open | | 9.0.4-open ...
Brew has an openjdk@8
formula.
$ brew info openjdk@8
$ brew install openjdk@8
Another option is installing AdoptOpenJDK 8 via cask.
$ brew tap homebrew/cask-versions # cask-versions must be tapped to get access to this caskto different cask versions.
$ brew search jdk # Find `adoptopenjdk8` in the casks
$ brew cask info adoptopenjdk8 # Confirm information about the cask. Note that this is an AdoptOpenJDK build of OpenJDK.
$ brew cask install adoptopenjdk8 # Install the AdoptOpenJDK build of OpenJDK8
See the AdoptOpenJDK HomeBrew Tap Github Repo for an alternative taproom with more AdoptOpenJDK versions.
- 💀OBSOLETE💀: It appears Java 7 is no longer available in
homebrew/cask-versions
. It used to be available atcaskroom/versions/java7
.
# THIS IS OBSOLETE. INCLUDED FOR REFERENCE PURPOSES.
$ brew cask info caskroom/versions/java7 # Query info about Java cask installation beforehand
$ brew cask install caskroom/versions/java7 # For Java 7
If you know how to find Java 7 on Homebrew, please leave a comment on how to do so and we can add it in here. 😜
- Note from the metadata in
brew info java6
that this is JDK is for Apple OSX.
$ brew info java6
java6: 1.6.0_65-b14-468
https://support.apple.com/kb/DL1572
Not installed
From: https://github.com/Homebrew/homebrew-cask-versions/blob/HEAD/Casks/java6.rb
==> Name
Apple Java 6 Standard Edition Development Kit
==> Description
Legacy runtime for the Java programming language
==> Artifacts
JavaForOSX/JavaForOSX.pkg/Payload/Library/Java/JavaVirtualMachines/1.6.0.jdk -> /Library/Java/JavaVirtualMachines/1.6.0.jdk (Generic Artifact)
$ brew tap homebrew/cask-versions # Make sure you have cask-versions tapped
$ brew cask info java6 # Double check information about the cask.
$ brew cask install java6 # Install Java6 for OSX
- The MacOS Java install location is
/Library/Java/JavaVirtualMachines/
.- Certain formulae, such as
openjdk
, do not automatically install into the actual/Library/Java/JavaVirtualMachines/
. Instead, the formula will suggest to you in the installation/info caveats to symlink it into that location.
- Certain formulae, such as
- When upgrading Java installations with Homebrew
- Be aware upgrades will overwrite the
cacerts
truststore file (if you have edited that). - Be aware that the JDK install directory's name may fall out of date when you perform the upgrade. You may have to manually rename the directory, and make tweaks to your configurations accordingly.
- Be aware upgrades will overwrite the
- I recommend jEnv for switching between multiple Java environments on MacOS.
- I think it's generally wise to have
homebrew/cask
andhomebrew/cask-versions
tapped. They are practically core. - SDKMAN is a SDK downloader and manager that can be a viable alternative to Homebrew for installing JDKs and even managing them.
On arm Macs brew uses
/opt/homebrew/opt
instead of/usr/local/opt
. Maybe that is the reason for the different location.