Installing Java on macOS with Homebrew
Homebrew provides the simplest and most efficient way to install and manage Java development kits on macOS, supporting both OpenJDK and Oracle JDK distributions.
Problem Overview
When installing Java via Homebrew, many users encounter issues where the system doesn't recognize the installed JDK, resulting in error messages like:
The operation couldn't be completed. Unable to locate a Java Runtime.
Please visit http://www.java.com for information on installing Java.This occurs because Homebrew installs Java as "keg-only" to avoid conflicts with macOS's built-in Java, requiring additional configuration steps.
Solution: Installing Java with Homebrew
Basic Installation (Latest OpenJDK)
To install the latest stable version of OpenJDK:
brew install javaAfter installation, verify it works:
java --versionIf you still get the "Unable to locate a Java Runtime" error, create the necessary symlink:
sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdkInstalling Specific Java Versions
For development projects requiring specific Java versions:
# Install Java 8, 11, 17, or other available versions
brew install openjdk@8
brew install openjdk@11
brew install openjdk@17
brew install openjdk@21For each version, create the appropriate symlink:
# For Java 11
sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
# For Java 17
sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdkOracle JDK Installation
If you specifically need Oracle's JDK:
brew install --cask oracle-jdkWARNING
Oracle JDK may have different licensing terms compared to OpenJDK. Review Oracle's license agreement before use.
Managing Multiple Java Versions
Using Aliases for Version Switching
Add these aliases to your ~/.zshrc or ~/.bash_profile:
alias j8="export JAVA_HOME=/opt/homebrew/opt/openjdk@8 ; java -version"
alias j11="export JAVA_HOME=/opt/homebrew/opt/openjdk@11 ; java -version"
alias j17="export JAVA_HOME=/opt/homebrew/opt/openjdk@17 ; java -version"
alias j21="export JAVA_HOME=/opt/homebrew/opt/openjdk@21 ; java -version"Reload your shell configuration:
source ~/.zshrc # or source ~/.bash_profileNow switch between versions using the aliases: j8, j11, j17, or j21.
Using jenv for Advanced Version Management
For more sophisticated version management, install jenv:
brew install jenvConfigure your shell (for Zsh):
echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(jenv init -)"' >> ~/.zshrc
eval "$(jenv init -)"Add installed JDKs to jenv:
jenv add /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home/
jenv add /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home/Set global or local Java version:
jenv global openjdk64-21.0.7 # Set global version
jenv local openjdk64-17.0.10 # Set version for current directoryTroubleshooting Common Issues
Finding the Correct Symlink Path
If unsure about the symlink path, use brew info:
brew info openjdk@17Look for the symlink instruction in the output:
For the system Java wrappers to find this JDK, symlink it with
sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdkSetting JAVA_HOME Environment Variable
Add this to your shell configuration file:
echo 'export JAVA_HOME=$(/usr/libexec/java_home)' >> ~/.zshrcReload with source ~/.zshrc to apply changes.
Ensuring Homebrew Java Takes Precedence
Add Homebrew binaries to the beginning of your PATH:
echo 'export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"' >> ~/.zshrcVerifying Installation
Check all detected Java versions:
/usr/libexec/java_home -VVerify current Java version:
java -versionCheck JAVA_HOME is set correctly:
echo $JAVA_HOMEBest Practices
- Regular Updates: Keep your Java installations updated with
brew upgrade - Clean Up: Remove old versions with
brew uninstall openjdk@Xwhen no longer needed - Project-Specific Configuration: Use jenv or
.java-versionfiles to specify JDK versions per project - Backup Configuration: Keep your shell configuration files under version control
TIP
For Intel-based Macs, replace /opt/homebrew/ with /usr/local/ in all paths, as Homebrew uses different installation directories based on architecture.
By following these instructions, you can effectively manage multiple Java versions on macOS using Homebrew, ensuring compatibility with various development projects while maintaining a clean system configuration.