Question

How to Change the Default Java JDK Version on macOS

javamacos

Question

How can you change the default Java version on macOS so that terminal commands like java and javac use a specific JDK installation?

Short Answer

By the end of this page, you will understand how macOS chooses a Java version, how to check installed JDKs, and how to change the default JDK temporarily or permanently using JAVA_HOME and the java_home tool.

Concept

On macOS, the Java version used by commands such as java, javac, and many build tools is usually controlled by the JAVA_HOME environment variable and the system's installed JDK locations.

A JDK (Java Development Kit) includes tools for developing and running Java programs. If you install multiple versions, such as Java 8, 11, 17, or 21, you may need to choose which one your shell or project should use.

macOS provides a helpful command-line utility called java_home that can locate installed JDKs. Instead of manually typing long installation paths, you can use this tool to select a version safely.

This matters because different projects often require different Java versions:

  • Older enterprise applications may require Java 8
  • Some Android or backend projects may use Java 11 or 17
  • Newer frameworks may expect Java 21
  • Build tools like Maven, Gradle, and IDEs often depend on the correct JDK

Changing the default Java version usually means one of these:

  • Setting it for the current terminal session only
  • Setting it permanently in your shell config file
  • Setting it for one project or script only

The most common and reliable approach on macOS is to set JAVA_HOME using /usr/libexec/java_home.

Mental Model

Think of Java versions like different toolboxes stored in your garage.

  • Each installed JDK is one toolbox
  • JAVA_HOME is the label telling your system which toolbox to open by default
  • The java command uses that label to find the correct tools

If you change the label, your terminal starts using a different toolbox without uninstalling the others.

So you are not replacing Java entirely. You are choosing which installed Java version should be used first.

Take Quiz

Syntax and Examples

The most important commands are:

/usr/libexec/java_home -V

This lists all installed JDKs.

export JAVA_HOME=$(/usr/libexec/java_home -v 17)

This sets Java 17 for the current shell session.

java -version
javac -version

These confirm which Java version is currently active.

Example: switch to Java 17 temporarily

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH="$JAVA_HOME/bin:$PATH"
java -version

Example output might be:

openjdk version "17.0.10" 2024-01-16

Example: make Java 21 the default permanently

If you use zsh on modern macOS, add this to ~/.zshrc:

export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH="$JAVA_HOME/bin:$PATH"

Then reload your shell:

source ~/.zshrc

Now every new terminal session will use Java 21.

View the selected JDK path

echo $JAVA_HOME

Example output:

/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home

This is useful when debugging build-tool configuration.

Step by Step Execution

Consider this example:

export JAVA_HOME=$(/usr/libexec/java_home -v 11)
export PATH="$JAVA_HOME/bin:$PATH"
java -version

Here is what happens step by step:

  1. /usr/libexec/java_home -v 11 asks macOS to find an installed JDK that matches version 11.
  2. The command returns a path such as:
    /Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home
    
  3. export JAVA_HOME=... stores that path in the JAVA_HOME environment variable.
  4. export PATH="$JAVA_HOME/bin:$PATH" puts that JDK's bin directory at the front of your command search path.
  5. When you run java -version, your shell finds java inside the selected JDK first.
  6. The terminal prints the Java 11 version, confirming the switch worked.

Small trace example

/usr/libexec/java_home -V
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
echo $JAVA_HOME
java -version

Possible flow:

  • First command lists installed JDKs
  • Second command chooses version 17
  • Third command prints the chosen path
  • Fourth command verifies that java now uses that version

Real World Use Cases

Changing the default Java version on macOS is common in real development work.

Common situations

  • Running old projects: A legacy application may only build correctly with Java 8.
  • Using modern frameworks: New Spring Boot or backend services may require Java 17 or later.
  • Working across multiple repositories: One project uses Java 11, another uses Java 21.
  • CI debugging locally: You may need your local machine to match the Java version used in a deployment pipeline.
  • Build tool compatibility: Maven, Gradle, and Ant often read JAVA_HOME.
  • IDE integration: IntelliJ IDEA, Eclipse, and VS Code may use system Java settings or project-specific JDKs.

Script and automation examples

  • A shell script can set a specific JDK before running a build
  • A project setup guide can tell teammates which version to export
  • A deployment script can verify java -version before packaging an application
Take Quiz

Real Codebase Usage

In real projects, developers rarely change Java versions randomly. They usually do it in structured ways.

Common patterns

  • Project-specific setup: A project's README may instruct developers to use Java 17.
  • Shell profile defaults: Developers set a personal default version in ~/.zshrc or ~/.bash_profile.
  • Temporary overrides: Before running one build, they export a different JAVA_HOME in that terminal only.
  • Validation checks: Scripts often verify the version:
java -version
  • Guard clauses in scripts: A setup script may stop early if the wrong Java version is active.
if ! java -version 2>&1 | grep '17' >/dev/null; then
  echo "Java 17 is required"
  exit 1
fi
  • Environment-based configuration: Teams avoid hardcoding absolute JDK paths when possible and use java_home for portability.

Why JAVA_HOME is preferred

Many Java tools look for JAVA_HOME directly. Even if java -version works, some tools can still fail if JAVA_HOME is missing or points to the wrong JDK.

That is why a common real-world setup includes both:

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH="$JAVA_HOME/bin:$PATH"

Common Mistakes

Here are some beginner mistakes that often cause confusion.

1. Setting JAVA_HOME to the wrong path

Broken example:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-17.jdk

This may be incomplete for many tools. The JDK home usually ends with /Contents/Home on macOS.

Better:

export JAVA_HOME=$(/usr/libexec/java_home -v 17)

2. Forgetting to reload the shell config

If you add lines to ~/.zshrc but do not reload it, the current terminal will not see the change.

source ~/.zshrc

3. Updating JAVA_HOME but not PATH

Sometimes java still points to another location because PATH is unchanged.

Use both:

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH="$JAVA_HOME/bin:$PATH"

4. Using the wrong shell config file

Modern macOS usually uses zsh, not bash.

  • zsh: ~/.zshrc
  • bash: ~/.bash_profile or ~/.bashrc

Check your shell:

echo $SHELL

5. Assuming the JDK is installed when only a JRE is available

Older setups may not include development tools like javac.

Check both:

java -version
javac -version

6. Manually hardcoding fragile paths

Broken approach:

export JAVA_HOME=/some/path/that/might/change

Better approach:

export JAVA_HOME=$(/usr/libexec/java_home -v 11)

This is easier to maintain when installations differ between machines.

Comparisons

ApproachWhat it doesBest forNotes
export JAVA_HOME=$(/usr/libexec/java_home -v 17)Sets the active JDK using macOS lookupMost users on macOSRecommended and portable
Hardcoded JDK pathPoints directly to one installationSpecial casesMore fragile if paths change
Temporary terminal settingChanges Java only for the current shellTesting and one-off buildsDisappears when terminal closes
Shell profile settingChanges Java for future terminal sessionsPersonal default setupRequires reload or new terminal

JAVA_HOME vs PATH

SettingPurposeWhy it matters
JAVA_HOMETells tools where the JDK is installedMaven, Gradle, IDEs, and scripts often depend on it
PATHTells the shell where to find commands like java and javacAffects which executable runs when you type a command

Temporary vs permanent change

TypeHowWhen to use
TemporaryRun export in the terminalSwitching versions for one task
PermanentAdd export lines to shell configSetting your default Java version

zsh vs bash

ShellCommon config file on macOS
zsh~/.zshrc
bash~/.bash_profile or ~/.bashrc
Take Quiz

Cheat Sheet

Check installed Java versions

/usr/libexec/java_home -V

Set Java temporarily for current terminal

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH="$JAVA_HOME/bin:$PATH"

Verify active version

java -version
javac -version
echo $JAVA_HOME

Make Java default permanently for zsh

Add to ~/.zshrc:

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH="$JAVA_HOME/bin:$PATH"

Reload:

source ~/.zshrc

Common files

  • ~/.zshrc for zsh
  • ~/.bash_profile for bash

Useful rules

  • Prefer /usr/libexec/java_home over hardcoded paths
  • On macOS, JDK home usually ends in /Contents/Home
  • Set both JAVA_HOME and PATH for best compatibility
  • Use java -version and javac -version to confirm the switch

FAQ

How do I check which Java version is currently active on macOS?

Run:

java -version
echo $JAVA_HOME

This shows the active runtime version and the selected JDK path.

How do I list all installed JDK versions on macOS?

Use:

/usr/libexec/java_home -V

This prints all detected Java installations.

How do I switch Java versions only for the current terminal session?

Run:

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
export PATH="$JAVA_HOME/bin:$PATH"

That change lasts until the terminal is closed.

How do I make a Java version the default permanently?

Add the export lines to your shell config file such as ~/.zshrc, then reload it with source ~/.zshrc.

Why is java -version correct but my build tool still fails?

Some tools use JAVA_HOME directly. Make sure JAVA_HOME points to the correct JDK, not just that java is on your PATH.

What is the difference between JDK and JRE?

A JDK includes development tools like javac. A JRE is mainly for running Java applications. For development, use a JDK.

Which shell config file should I edit on macOS?

Most modern macOS systems use zsh, so edit ~/.zshrc. You can confirm with:

echo $SHELL
Take Quiz

Mini Project

Description

Create a small shell setup that lets you switch between installed Java versions on macOS and verify the result. This mirrors real development workflows where different projects require different JDK versions.

Goal

Build a reusable terminal helper that switches to a chosen Java version and confirms that the correct JDK is active.

Requirements

  • List installed Java versions on the machine
  • Create a shell function that accepts a Java version number
  • Set both JAVA_HOME and PATH based on that version
  • Print the selected JAVA_HOME
  • Verify the active version with java -version
Take Quiz

Keep learning

Related questions

View more