🍎 Installing and Managing Java on macOS
September 07, 2020
Update 2021-10-13: AdoptOpenJDK has migrated to the Eclipse Foundation and is now Temurin. This post has been updated to reflect this migration.
Changes to how Java is released and licensed may have macOS users feeling more lost than usual when considering their options for installing the JDK. Given the licensing changes Oracle made to Java after version 1.8, using Oracle’s installer may not always be an option. With Java’s new six-month release cycle, developers are more likely to need a handful of different versions of the JDK installed. In this post, I explain how I use Homebrew to install Eclipse Temurin packages and manage multiple versions of Java with built-in shell tools.
Installing Java
-
Execute
java -version
to double-check that Java is truly gone from the environment. -
Add the Cask Versions Tap. This is necessary to install previous releases.
brew tap homebrew/cask-versions
-
Find the Eclipse Temurin HomeBrew packages for the versions of Java you need
brew search temurin
-
Install the JDK versions you need e.g.
brew install --cask temurin11
-
Configure
JAVA_HOME
in your shell with the default version of Java. This guide assumes you use ZSH because that is the default shell since macOS Catalinaexport JAVA_HOME=$(/usr/libexec/java_home -v 11) path+=$JAVA_HOME/bin
-
Reload the shell configuration confirm that Java works
. ~/.zshrc java -version
Switching Java Versions
Users can install multiple JDKs by installing multiple Temurin HomeBrew
packages. The macOS program /usr/libexec/java_home
helps users configure their
JAVA_HOME
environment variable.
# switches to JDK 14
export JAVA_HOME=$(/usr/libexec/java_home -v 14)
There is no need to update the PATH
variable. The ZSH path
array will
automatically update to reflect the changes to the JAVA_HOME
variable.
This command may be too verbose to type every time, so the HomeBrew AdoptOpenJDK Tap README recommends adding this function to your shell configuration to succinctly switch your JDK version:
jdk() {
version=$1
export JAVA_HOME=$(/usr/libexec/java_home -v"$version");
java -version
}
Automatically Switching Java Versions
The command jdk 1.8
is succinct, but you still need to remember to type it
when switching between a handful of different projects. To save yourself the
trouble of remembering, you can configure your shell to automatically update
JAVA_HOME
whenever you change to your project’s directory. This is a popular
feature in shell scripts like jenv and
virtualenv.
Fortunately, this feature is incredibly easy to emulate with some ZSH
configuration.
First, in your project’s root directory, store the version of Java the project
requires in a new .java-version
file. The name .java-version
is significant
only because this is the same name that the analogous jenv feature uses, and
using a common name helps share this configuration with any jenv users that
contribute to your project.
echo 1.8 > .java-version
Next, we need to add a hook to our ZSH configuration that will look for and act
on this file whenever the shell changes directories. Add the following to
$HOME/.zshrc
.
# automatic java_home switch when .java-version detected
function chpwd() {
if [[ -f $PWD/.java-version ]]; then
version=$(cat $PWD/.java-version)
export JAVA_HOME=$(/usr/libexec/java_home -v $version)
fi
}
Lastly, reload your ZSH configuration and test it out
# create two test project directories
mkdir java-8-project java-11-project
# configure each test project directory to use a different version of Java
echo 1.8 > java-8-project/.java-version
echo 11 > java-11-project/.java-version
# test Java version in java-8-project
cd java-8-project
java -version
# switch to java-11-project and test Java version
cd ../java-11-project
java -version
Why not use the Oracle installer?
Traditionally, the most straightforward way to download Java has always been to search “download Java” and follow the first link from Oracle to download the macOS installer. Oracle’s macOS installer takes care of installing and automatically updating Java. One of the problems with the installer is that it will insist on upgrading to the latest version of Java. Especially given Java’s new six-month release cycle, upgrading to the latest version is probably too volatile for most large projects.
The installer is not the only reason you might avoid a Java release from Oracle. Oracle has made its licensing more restrictive, and you may need a paid subscription to use it. For example, After April 16, 2019, developers can no longer use Oracle’s Java 1.8 release for commercial purposes without buying a subscription.
Why Eclipse Temurin?
There are a lot of OpenJDK distributions to choose from. The excellent article Is Java Still Free is the best resource for navigating these choices. The two most important things to remember are:
- The open-source project OpenJDK does not distribute binary releases. It makes the OpenJDK source code available for others to build and distribute OpenJDK distributions.
- Companies and organizations that provide OpenJDK distributions differentiate their offerings primarily through maintenance, support, and added features.
The average Java developer wants an OpenJDK distribution that is simple, free, has no strings attached, and is easy to install. OpenJDK distributions from the Eclipse Temurin project fit these criteria well. Temurin, formerly AdoptOpenJDK, is part of the Eclipse Foundation and makes OpenJDK distributions freely available. They do not offer commercial support, so they are not trying to up-sell developers. Their mission is
Providing the Java community with rock-solid runtimes and associated tools that can be used free of charge, without usage restrictions on a wide range of platforms.
Sounds good to me 😁. Temurin is readily available in Docker images on Docker Hub, in HomeBrew packages, and in archives on adoptium.net.