Skip to content

Instantly share code, notes, and snippets.

@gwpantazes
Last active November 13, 2024 09:42
Show Gist options
  • Save gwpantazes/50810d5635fc2e053ad117b39b597a14 to your computer and use it in GitHub Desktop.
Save gwpantazes/50810d5635fc2e053ad117b39b597a14 to your computer and use it in GitHub Desktop.
How to install different JDK versions on MacOS with Homebrew

How To Install Different JDK Versions on MacOS with Homebrew

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.

Table of Contents

Preface

This Guide Favors OpenJDK

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.

About Command Line Outputs

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.

Introduction Homebrew

Hombrew Setup

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).

Getting an Overview: How to Search Homebrew for Java formulae

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)

Installing Java

Early Access (EA) OpenJDK Feature Release

The java-beta cask contains the OpenJDK Early Access JDK.

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!

Latest Stable Generally Available (GA) OpenJDK Feature Release (Java 15, 16, etc...)

  • The openjdk is a formula avilable on homebrew/core. You don't have to tap any additional taprooms/caskrooms.
  • There is a java alias which points to openjdk, 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.

OpenJDK 11

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 to openjdk@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

Older OpenJDK Feature Release (Java 9, 10, 12, 13, 14, etc.)

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

Java 8

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.

Java 7

  • 💀OBSOLETE💀: It appears Java 7 is no longer available in homebrew/cask-versions. It used to be available at caskroom/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. 😜

Java 6

  • 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

Notes

  • 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.
  • 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.
  • I recommend jEnv for switching between multiple Java environments on MacOS.
  • I think it's generally wise to have homebrew/cask and homebrew/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.
@soulflyer
Copy link

/usr/local/opt/ doesn't appear to exist on Monterey.

@jlgridley Not sure why /usr/local/opt doesn't exist for you - I"m also on Monterey and I do have /usr/local/opt. If there's any news about the correct different location, please let us know.

On arm Macs brew uses /opt/homebrew/opt instead of /usr/local/opt. Maybe that is the reason for the different location.

@clintonmedbery
Copy link

Looks like adopt is left behind, I used:
brew install --cask temurin8

@Kamal2301
Copy link

Thank you @gwpantazes 👍🏻

@tinu1976ch
Copy link

If you need to have openjdk first in your PATH run:
echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc

/usr/local/opt/ doesn't appear to exist on Monterey.

@jlgridley Not sure why /usr/local/opt doesn't exist for you - I"m also on Monterey and I do have /usr/local/opt. If there's any news about the correct different location, please let us know.

i use monterey 12.7 and do NOT have /usr/local/opt too
i found my java in the following location:
/Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/bin
and this path was found in my PATH

hope, this information helps....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment