Skip to content
Java getting started 5 min read

Setting the PATH

Before you can compile and run Java programs from the command line, your operating system needs to know where javac and java live. That knowledge comes from the PATH environment variable — a list of directories the OS searches whenever you type a command.

What Is the PATH?

Every operating system keeps a special variable called PATH (or Path on Windows). When you type javac HelloWorld.java in a terminal, the OS walks through each directory listed in PATH, one by one, until it finds an executable named javac. If it never finds one, you get the dreaded error:

'javac' is not recognized as an internal or external command  (Windows)
bash: javac: command not found                                (Linux/macOS)

Adding the JDK’s bin folder to PATH fixes this permanently.

Note: The PATH variable does not move any files. It simply tells the OS where to look. The JDK stays exactly where you installed it.


Step 1 — Find Your JDK Installation

Before editing PATH you need to know where the JDK was installed. Common default locations:

Operating SystemTypical JDK Location
WindowsC:\Program Files\Java\jdk-21
macOS (Homebrew)/opt/homebrew/opt/openjdk@21
macOS (Oracle installer)/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
Ubuntu/Debian (apt)/usr/lib/jvm/java-21-openjdk-amd64
Fedora/RHEL (dnf)/usr/lib/jvm/java-21-openjdk

To confirm the exact path after installing, run:

# Windows (PowerShell)
Get-Command javac | Select-Object -ExpandProperty Source

# macOS / Linux
which javac
readlink -f $(which javac)   # follows symlinks to the real path

The folder you want is the JDK root — the one that contains a bin sub-directory with javac inside it. This root path is conventionally stored in a separate variable called JAVA_HOME.


JAVA_HOME is a convention used by build tools (Maven, Gradle, Ant) and many IDEs. You set it once, then reference it in PATH so you only have one place to update when you upgrade Java.

Windows

  1. Press Win + R, type sysdm.cpl, and press Enter.
  2. Click AdvancedEnvironment Variables.
  3. Under System variables, click New:
    • Variable name: JAVA_HOME
    • Variable value: C:\Program Files\Java\jdk-21 (your actual path)
  4. Click OK.

macOS / Linux (shell profile)

Add these lines to your shell’s startup file:

  • bash: ~/.bashrc or ~/.bash_profile
  • zsh (default on macOS): ~/.zshrc
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home

Tip: On macOS with multiple JDKs installed you can use the dynamic helper instead of a hard-coded path:

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

Step 3 — Add the JDK bin Folder to PATH

Windows

  1. In the Environment Variables dialog, find the existing Path variable under System variables and click Edit.
  2. Click New and add:
    %JAVA_HOME%\bin
  3. Click OK on every dialog to save.
  4. Open a new Command Prompt (existing windows do not pick up the change) and verify:
javac -version
java -version

Output:

javac 21.0.3
java version "21.0.3" 2024-04-16 LTS

macOS / Linux

Append to the same startup file you edited above:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH

Then reload the file without restarting your terminal:

source ~/.zshrc   # or ~/.bashrc

Verify:

javac -version
java -version

Output:

javac 21.0.3
openjdk version "21.0.3" 2024-04-16

Warning: Placing $JAVA_HOME/bin before $PATH (as shown above) ensures your explicitly installed JDK takes priority over any system-managed Java. If you put it at the end, a different Java version already on PATH may be picked up first.


Verifying the Full Setup

Once PATH is set, run a quick sanity check:

javac -version   # compiler — from the JDK
java  -version   # runtime  — from the JRE bundled inside the JDK
jar   --version  # archive tool

All three executables live in $JAVA_HOME/bin. If any command fails, double-check the spelling of the path and make sure you opened a new terminal after saving the change.

You can also print the full resolved path to confirm which Java the system picks:

# macOS / Linux
which javac          # e.g. /opt/homebrew/opt/openjdk@21/bin/javac

# Windows (PowerShell)
(Get-Command javac).Source

Common Issues and Fixes

SymptomCauseFix
javac: command not found after setting PATHTerminal was not restartedOpen a new terminal window
Wrong Java version printedAn older JDK is earlier in PATHMove $JAVA_HOME/bin to the front of PATH
JAVA_HOME is set but javac still not foundForgot to add $JAVA_HOME/bin to PATHAdd the bin sub-directory, not the root
Path with spaces causes errors on WindowsUnquoted pathUse %JAVA_HOME% (the variable), not the raw path with spaces
macOS shows /usr/bin/javac instead of your JDKApple’s shim is first in PATHExport JAVA_HOME and put $JAVA_HOME/bin before /usr/bin

Managing Multiple Java Versions

Real-world projects often require different Java versions — a legacy service on Java 8, a new microservice on Java 21. Two popular tools make switching effortless:

  • SDKMAN! (macOS / Linux): install and switch JDKs with sdk install java 21-tem and sdk use java 21-tem.
  • Jabba (cross-platform): similar concept.

Both tools manage JAVA_HOME and PATH automatically, so you never edit a startup file again.


Under the Hood

When your shell starts, it reads its startup file (e.g. ~/.zshrc) and stores JAVA_HOME and PATH as environment variables — key/value pairs held in the shell process’s memory. Every child process (like a javac invocation) inherits a copy of these variables from its parent shell.

On Linux and macOS the kernel’s execve system call passes the environment array to the new process. The C runtime inside javac calls getenv("PATH") to retrieve the string, then splits it on : (or ; on Windows) to get a list of directories. It opens each directory and checks for a file named javac with execute permission. The first match wins — which is why order matters.

On Windows, the Registry stores system-wide environment variables under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. The PATH you edit in the GUI is read from there. New processes inherit the updated value; existing processes keep their old copy, which is why you must open a new terminal.

Note: IDEs such as IntelliJ IDEA and Eclipse read JAVA_HOME at startup to locate the JDK. If you change JAVA_HOME after the IDE is open, restart it to pick up the new value.


Last updated June 13, 2026
Was this helpful?