Java

There is no AI here. All content is human-authored and tested for accuracy.

Unable to Locate a Java Runtime

Fix the macOS Java error 'The operation couldn't be completed. Unable to locate a Java Runtime' on Mac. Troubleshoot Java on macOS, set JAVA_HOME, configure Mac PATH, and resolve java command not found errors.

The Unable to locate a Java Runtime message appears when macOS can't find a JDK installation (the Java Development Kit). This happens because Apple's macOS has a built-in Java system launcher that prompts you to install Java when none exists. Here's how to diagnose the problem and fix it.

Before You Get Started

You'll need a terminal application to fix Java errors and develop with Java. Apple includes the Mac Terminal but I prefer Warp Terminal. Warp is an easy-to-use terminal application, with AI assistance to help you learn and remember terminal commands. Download Warp Terminal now; it's FREE and makes coding easier when working with Java.

Understanding the Error

On a fresh macOS installation without Java, running java in a terminal application triggers Apple's Java system launcher at /usr/bin/java. Instead of executing Java, the launcher (or "stub") displays a message:

The operation couldn't be completed. Unable to locate a Java Runtime.
Please visit http://www.java.com for information on installing Java.

When it runs, the Java system launcher searches for Java in the standard macOS location: /Library/Java/JavaVirtualMachines/. This error means macOS ran the /usr/bin/java stub but couldn't locate an actual Java installation. If Java hasn't been installed, the stub tells users they need to install Java.

Why macOS Has a Java Stub

Apple's macOS included a pre-installed Java runtime many years ago, but removed it starting with macOS 10.7 (Lion) in July 2011. Rather than leaving users with a confusing "command not found" error, Apple created a stub at /usr/bin/java that detects when Java is missing and provides a helpful message. This stub is protected by System Integrity Protection and can't be modified or removed.

A Cautionary Note for Developers

The help message says "please visit http://www.java.com" but many developers advise: don't visit Oracle's java.com to download Java! It's intended for consumers who need the Java 8 JRE consumer download. Oracle sends developers to Oracle's Java web pages for a JDK download that requires a license. Oracle owns the trademark and wants to sell enterprise licenses of the Oracle JDK distribution. For developers, Java is open source and available for free from many other vendors. Stick to free versions unless you're working for a company that already has a paid Oracle Java licensing arrangement. See my article Download Java for Mac for a comparison of free options for obtaining Java.

Error Variations

You may see different error messages depending on context:

  • GUI dialog – A popup window offering to take you to java.com or the Oracle website
  • Terminal messageUnable to locate a Java Runtime displayed in the console
  • java_home utilityThe operation couldn't be completed. Unable to locate a Java Runtime.

On Linux or in unusual macOS configurations where /usr/bin isn't in PATH, you might instead see shell errors like zsh: command not found: java or bash: java: command not found. These indicate the shell can't find any java executable at all. See the article Command not found.

What to Do Next

Your next steps depend on whether Java is actually not installed or if it was previously installed but not configured correctly.

If you've installed Java and still get the error Unable to locate a Java Runtime, this article will help you troubleshoot.

About the Shell

See the article Mac Shell Configuration to learn about the shell.

Zsh (the Z shell) is a program that runs in a terminal application that interprets Unix commands and gives us the command line interface. You'll need to configure the shell to set environment variables, which are essential to make programs available or change program behavior. You may also want to configure other shell features, such as the $PATH environment variable which determines the directories the shell searches for executable files. See the guide Mac PATH for information.

Two environment variables are important for running Java: JAVA_HOME and PATH. Read Set JAVA_HOME on Mac and Java PATH on Mac for complete configuration instructions.

Before you troubleshoot, you need to know which shell you're running. Apple's macOS Catalina (10.15), released in October 2019, and later versions use Zsh as the default shell. Older Macs or manually configured systems may use Bash.

Check your current shell:

$ echo $0

This returns -zsh or -bash indicating your active shell. The shell determines which configuration file you'll edit later.

Check your default shell:

$ echo $SHELL

This returns /bin/zsh or /bin/bash so you'll know which configuration file to edit later.

Understanding JAVA_HOME and PATH

JAVA_HOME is an environment variable pointing to your JDK installation directory. Many Java tools (Maven, Gradle, IntelliJ, Eclipse) use JAVA_HOME to locate Java. It should be set to use JDKs installed in the standard macOS location /Library/Java/JavaVirtualMachines/. JAVA_HOME should point to the JDK home directory, not the bin subdirectory:

  • Correct: /Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home
  • Wrong: /Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home/bin

PATH is a colon-separated list of directories. When you type a command, the shell searches these directories left to right until it finds a matching executable. Order matters because directories listed first take priority over the macOS stub at /usr/bin/java. A standard Java installation should work with the default /usr/bin in the Path, allowing the /usr/bin/java Java system launcher to locate JDKs or symlinks in the standard macOS location /Library/Java/JavaVirtualMachines/. It's best to install a JDK so this works as intended, without any need to modify the PATH.

Diagnose the Problem

Before applying fixes, run these commands to identify the root cause. The results determine which solution you need.

Check if Java is Installed

Use Apple's java_home utility to list installed Java versions:

$ /usr/libexec/java_home -V

This command lists all Java Development Kits (JDKs) installed on your Mac with their paths and version numbers.

If you see output like this, Java is installed:

Matching Java Virtual Machines (1):
    25.0.1 (arm64) "Eclipse Adoptium" - "OpenJDK 25.0.1" /Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home

If you see this, Java is not installed:

The operation couldn't be completed. Unable to locate a Java Runtime.

Check if Java is in PATH

The PATH environment variable tells your shell where to find executables. Check if Java's directory is included:

$ which java
/usr/bin/java

This shows the full path to the java executable that should run. If it returns only /usr/bin/java, that's the macOS stub, not a real Java installation. If it returns nothing, Java isn't in your PATH at all.

View your complete PATH:

$ echo $PATH

Directories are separated by colons, and the shell searches them left to right. Ordinarily, Java will not appear in the PATH because /usr/bin/java is enough to find and run the Java system launcher which looks for JDKs in the standard macOS location /Library/Java/JavaVirtualMachines/. See the article Java PATH. With a Homebrew Java installation, a symlink in /Library/Java/JavaVirtualMachines/ should resolve to Homebrew's Caskroom or Cellar storage. If you've installed Java with SDKMAN or another version manager, the PATH may have been modified to find a JDK elsewhere. If you see Java-related paths like /opt/homebrew/opt/openjdk/bin or a path containing JavaVirtualMachines, it's best to remove these from the PATH and reinstall Java to use the Java system launcher and /Library/Java/JavaVirtualMachines/.

Check JAVA_HOME

Many Java tools (Maven, Gradle, IDEs) use the JAVA_HOME environment variable to locate Java:

$ echo $JAVA_HOME

This should return a path like /Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home. If it returns nothing, JAVA_HOME isn't set. See the article Set JAVA_HOME.

Interpret Your Results

Scenario 1: Java not installed

  • /usr/libexec/java_home -V returns "Unable to locate a Java Runtime"
  • Solution: See below "Install Java."

Scenario 2: Java installed but not in PATH

  • /usr/libexec/java_home -V shows installed Java versions
  • which java returns nothing or only /usr/bin/java
  • Solution: See below "Configure JAVA_HOME."

Scenario 3: Configuration not loaded

  • Your .zprofile or .zshrc contains correct exports
  • java -version fails in current Terminal but works in a new window
  • Solution: See below "Reload Shell Configuration."

Install Java

If Java isn't installed, Homebrew provides the simplest installation method. Homebrew handles updates automatically, provides native Apple Silicon builds, and keeps paths consistent across Macs.

Homebrew offers two methods for installing Java:

Manual installation using a vendor's PKG file is an alternative if you don't want to use Homebrew. You download the installer directly from the vendor website, double-click to install, follow the wizard, and enter your admin password. Start with the article Download Java for Mac.

Configure JAVA_HOME

The JAVA_HOME environment variable tells Java tools where to find your JDK. Maven, Gradle, and most IDEs require JAVA_HOME to be set correctly.

Apple's /usr/libexec/java_home utility provides a dynamic way to set JAVA_HOME. Add this line to your ~/.zprofile:

export JAVA_HOME=$(/usr/libexec/java_home)

This automatically points to the default JDK without hardcoding paths. When you update Java, JAVA_HOME updates automatically.

For detailed configuration including version-specific settings, see:

Reload Shell Configuration

After editing ~/.zprofile or ~/.zshrc, changes don't apply to existing Terminal sessions. The shell reads configuration files only during startup.

Why Reloading is Necessary

When you open a Terminal window, Zsh loads your configuration files once. Editing those files changes what's stored on disk but doesn't affect running sessions. You must reload the configuration or start a new session.

Three Ways to Reload

Method 1: Source the configuration file (quickest)

You'll need to run source ~/.zprofile or close and reopen your terminal. This reads and executes the file in your current session. Changes apply immediately without losing command history.

For .zshrc, run source ~/.zshrc instead.

For Bash users, run source ~/.bash_profile.

Method 2: Replace the shell process

$ exec zsh

This replaces your current shell with a fresh one. It clears stale environment variables and removes temporary settings, which is equivalent to closing and reopening Terminal.

Method 3: Open a new Terminal window

Press ⌘-N (Command+N) for a new window or ⌘-T for a new tab.

New windows automatically load your configuration files. This is the simplest method but requires switching windows.

When to Use Each Method

  • source ~/.zprofile – Quick testing, preserve command history
  • exec zsh – Need completely clean environment
  • New window (⌘-N) – Prefer GUI, want to compare before/after

Verify Installation

After installing or configuring Java, run these commands to confirm everything works.

Check Java Version

$ java -version

Expected output:

openjdk version "25.0.1" 2025-10-21 LTS
OpenJDK Runtime Environment Temurin-25.0.1+12 (build 25.0.1+12-LTS)
OpenJDK 64-Bit Server VM Temurin-25.0.1+12 (build 25.0.1+12-LTS, mixed mode)

Check Java Compiler

$ javac -version

Expected output: javac 25.0.1 (version should match runtime).

Verify Environment Variables

$ echo $JAVA_HOME

Expected: A path like /Library/Java/JavaVirtualMachines/temurin-25.jdk/Contents/Home

Override Java Launcher with PATH

The PATH environment variable tells your shell where to search for executable programs. It's set (by convention) in ~/.zprofile but some developers set in in the ~/.zshenv shell configuration file.

A standard Java installation should work with the default /usr/bin in the Path, allowing the /usr/bin/java Java system launcher to locate JDKs or symlinks in the standard macOS location /Library/Java/JavaVirtualMachines/. It's best to install a JDK so this works as intended. However, as an alternative you can modify the PATH to circumvent the /usr/bin/java Java system launcher. You can override it by setting a $JAVA_HOME variable and adding $JAVA_HOME/bin to PATH to specify a different JDK executable. Or skip JAVA_HOME entirely and add the directory that contains a JDK Java bin.

Which Configuration File to Edit

On macOS, Zsh loads configuration files in this order:

  • ~/.zshenv – All shells; avoid for PATH because macOS overrides it
  • ~/.zprofile – Login shells; recommended for PATH and JAVA_HOME
  • ~/.zshrc – Interactive shells; best for aliases, prompts, shell features

Why .zprofile for PATH: Apple's macOS runs /usr/libexec/path_helper from /etc/zprofile during shell startup. If you set PATH in .zshenv, macOS appends your paths instead of prepending them. Setting PATH in .zprofile loads after path_helper, preserving your intended order.

Homebrew explicitly recommends ~/.zprofile for PATH settings on macOS. See .zshrc or .zprofile for an explanation. See the articles Mac Shell Configuration and Set Mac Path for further instructions.

For Bash users: Edit ~/.bash_profile instead of .zprofile.

Add Java to PATH

The /usr/libexec/java_home utility is Apple's recommended way to find Java installations. It automatically locates the default JDK without hardcoding paths.

Edit your ~/.zprofile shell configuration file. Add these lines:

# Java configuration
export JAVA_HOME=$(/usr/libexec/java_home)
export PATH="$JAVA_HOME/bin:$PATH"

The $() syntax captures the output of /usr/libexec/java_home and assigns it to JAVA_HOME. This approach automatically adapts when you update Java or switch versions.

For a specific Java version:

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

Read Set JAVA_HOME on Mac for configuration and troubleshooting.

Common Configuration Mistakes

Avoid these syntax errors that break PATH configuration:

Mistake 1: Using lowercase "path"

export path="/opt/homebrew/bin:$PATH"  # WRONG - case sensitive
export PATH="/opt/homebrew/bin:$PATH"  # CORRECT

Mistake 2: Setting JAVA_HOME to bin directory

export JAVA_HOME=/Library/Java/.../Home/bin  # WRONG
export JAVA_HOME=/Library/Java/.../Home      # CORRECT

Mistake 3: Forgetting $PATH at the end

export PATH="/opt/homebrew/opt/openjdk/bin"        # WRONG - overwrites entire PATH
export PATH="/opt/homebrew/opt/openjdk/bin:$PATH"  # CORRECT - prepends to existing

Mistake 4: Spaces around equals sign

export JAVA_HOME = $(/usr/libexec/java_home)  # WRONG
export JAVA_HOME=$(/usr/libexec/java_home)    # CORRECT

Mistake 5: Using single quotes with variables

export PATH='$JAVA_HOME/bin:$PATH'   # WRONG - variables not expanded
export PATH="$JAVA_HOME/bin:$PATH"   # CORRECT - variables expanded

Mistake 6: Setting JAVA_HOME but not PATH

export JAVA_HOME=$(/usr/libexec/java_home)  # Sets reference only
# Missing: export PATH="$JAVA_HOME/bin:$PATH"

JAVA_HOME is a reference variable. PATH is what the shell searches. You need both.

Mistake 7: Editing the wrong configuration file

Zsh ignores Bash configuration files. If you're using Zsh (the default since macOS Catalina in October 2019), edit ~/.zprofile or ~/.zshrc, not ~/.bash_profile or ~/.bashrc. Check your shell with echo $0.

Troubleshooting

Still Getting "Unable to locate a Java Runtime"

Symptoms:

  • Installed Java via Homebrew formula (not cask)
  • /usr/libexec/java_home -V still shows "Unable to locate a Java Runtime"

Cause: The JDK isn't in the standard macOS location that java_home searches.

Fix: If you installed via the OpenJDK formula, create the symlink:

$ sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk

Then verify:

$ /usr/libexec/java_home -V

Java Installed but Not Found

Symptoms:

  • java -version triggers the macOS dialog or "Unable to locate" message
  • /usr/libexec/java_home -V shows installed versions
  • which java returns /usr/bin/java (the stub)

Cause: Your PATH doesn't include the JDK's bin directory, so the macOS stub takes precedence.

Fix: Add Java to PATH:

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

Wrong Java Version Running

Symptoms:

  • java -version shows a different version than expected
  • Multiple Java installations exist
  • JAVA_HOME points to one version but java uses another

Diagnosis:

$ which java              # Shows actual binary being used
$ echo $JAVA_HOME         # Shows JAVA_HOME setting
$ /usr/libexec/java_home -V   # Lists all installations

PATH is searched left to right. The shell finds the first java executable, even if JAVA_HOME points elsewhere.

Fix: Set JAVA_HOME to the specific version and ensure it's at the front of PATH:

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

Configuration Changes Not Applied

Symptoms:

  • Edited ~/.zprofile but java -version still fails
  • New Terminal windows work but current one doesn't

Fix: You'll need to run source ~/.zprofile or close and reopen your terminal, then verify with java -version.

Permission Denied When Creating Symlink

Symptom:

ln: /Library/Java/JavaVirtualMachines/openjdk.jdk: Permission denied

Fix: Use sudo:

$ sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk

Enter your macOS password when prompted.

Bash vs Zsh Confusion

Symptoms:

  • Following Bash tutorials but changes don't apply
  • Edited .bash_profile with no effect

Diagnosis:

$ echo $0

If this returns -zsh, you're using Zsh. Edit ~/.zprofile or ~/.zshrc, not .bash_profile.

Apple's macOS Catalina (10.15), released in October 2019, and later default to Zsh.

Works in Terminal but Not in IDE

Symptoms:

  • java -version works in the terminal
  • IntelliJ, VS Code, or Eclipse can't find Java
  • Build tools fail with "JAVA_HOME not set"

Cause: IDEs don't inherit terminal environment variables. They launch their own processes without reading shell configuration files.

Fix: Configure Java directly in your IDE:

  • IntelliJ: File → Project Structure → SDKs
  • VS Code: Set java.jdk.ls.java.home in settings.json
  • Eclipse: Preferences → Java → Installed JREs

Java Works in One Terminal but Not Another

Cause: One terminal session has the configuration loaded; another was opened before you made changes.

Fix: Close all terminal windows and reopen, or run source ~/.zprofile in each existing window.

Related Errors

javac: command not found

The Java compiler (javac) is included in the JDK but not in a JRE (Java Runtime Environment). If java works but javac doesn't:

Diagnosis:

$ java -version    # Works
$ javac -version   # "command not found"

Cause: You may have a JRE instead of a full JDK, or PATH points to /usr/bin/java (the macOS stub) rather than a real JDK.

Modern OpenJDK distributions (Java 11+, released in September 2018 and later) only ship as complete JDKs, so this typically indicates a PATH issue.

Fix: Ensure $JAVA_HOME/bin is in your PATH:

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

jar: command not found

The jar tool (Java Archive utility) is included in the JDK. Same solution as javac: ensure you have a full JDK installed and PATH configured correctly:

$ jar --version

jshell: command not found

JShell (Java REPL) is available in Java 9 and later. If you're running Java 8, JShell doesn't exist. For Java 9+, the same PATH configuration applies:

$ jshell --version

All JDK Tools Missing

If java works but all other tools (javac, jar, jshell) are missing, your PATH likely points to /usr/bin/java (the macOS stub) rather than a real JDK.

Fix: Ensure $JAVA_HOME/bin is in PATH and takes priority:

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

Verify all tools are accessible:

$ ls $JAVA_HOME/bin/

Prevention and Best Practices

Use Homebrew for Managed Installations

Homebrew handles Java installation and updates with single commands:

  • Automated updates: brew upgrade keeps Java current
  • Simple uninstall: brew uninstall --cask temurin cleanly removes Java
  • Native builds: ARM64 builds verified automatically on Apple Silicon

Verify Immediately After Installation

Run verification commands right after installing:

$ java -version
$ javac -version
$ echo $JAVA_HOME
$ which java

Catching issues early is easier when installation steps are fresh in mind.

Read Homebrew Caveats

After installing Java via Homebrew formula, run:

$ brew info openjdk@25

Homebrew displays post-installation caveats with exact commands needed for setting a symlink. These provide architecture-specific instructions.

Use .zprofile for PATH Settings

Apple's macOS runs path_helper during shell startup. Setting PATH in ~/.zprofile ensures correct ordering. Avoid .zshenv for PATH on macOS.

Keep Configuration Simple

Start with minimal configuration:

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

Add complexity only when needed. Simple configurations are easier to troubleshoot.

Always Source After Configuration Changes

After editing shell configuration, you'll need to run source ~/.zprofile or close and reopen your terminal, then verify with java -version.

What's Next

Once Java is working, you may want to explore:

My mac.install.guide is a trusted source of installation guides for professional developers. Take a look at the Mac Install Guide home page for tips and trends and see what to install next.