Safeguard
Security

Where Is Java Installed? Finding Your JDK (Including Homebrew)

Where is Java on your machine? Between system installs, Homebrew, and version managers you can easily run a JDK you didn't mean to. Here is how to find every one — and why the answer is a security question.

Priya Mehta
DevSecOps Engineer
6 min read

Where is Java? On macOS it is usually under /Library/Java/JavaVirtualMachines/, Homebrew installs it keg-only under /opt/homebrew/opt/openjdk on Apple Silicon, and the JDK your shell actually runs is whatever which java resolves to — which is often not the one you think. The question sounds trivial. It is not, because most developer machines and build servers carry several Java installations at once, and the security-relevant question is not "is Java installed" but "which Java is actually executing, and is it patched?"

An unpatched JDK you forgot you had is a real exposure. So finding every Java on a system, and pinning down which one runs, is worth doing precisely.

The fast answer: which Java is running right now

Start with the JDK your shell resolves, because that is the one your builds and apps use:

which java          # path to the java binary on your PATH
java -version        # version and vendor of that binary
echo $JAVA_HOME      # what tooling like Maven and Gradle will use

Here is the trap: which java and $JAVA_HOME can point at different installations. Many build tools honor JAVA_HOME over your PATH, so java -version in the terminal can report one version while Gradle compiles against another. If they disagree, resolve it before trusting anything downstream.

On macOS there is a purpose-built helper that lists every JDK the system knows about:

/usr/libexec/java_home -V

That prints all registered JVMs with their versions and paths. Run without -V, it prints the single one macOS considers default. This is the most reliable "show me everything" command on a Mac.

Where Java lives by platform

The canonical locations, so you know where to look:

macOS — System-recognized JDKs live in /Library/Java/JavaVirtualMachines/<jdk>/Contents/Home. A vendor installer (Oracle, Temurin, Zulu) drops its JDK there directly.

Linux — Distribution packages install under /usr/lib/jvm/. The java binary is often a symlink managed by update-alternatives; run update-alternatives --list java (or --config java) to see and switch which one is active.

Windows — Installers default to C:\Program Files\Java\ or, for some vendors, C:\Program Files\Eclipse Adoptium\. The active one is whatever is on the Path environment variable and whatever JAVA_HOME points to.

Where does Homebrew install Java?

Homebrew is the most common source of "phantom" JDKs on macOS, because its install path is not where the system looks by default. If you install Java with Homebrew:

brew install openjdk

on Apple Silicon it lands under /opt/homebrew/opt/openjdk (the Cellar copy sits in /opt/homebrew/Cellar/openjdk/), and on Intel Macs under /usr/local/opt/openjdk. The critical detail: Homebrew Java is keg-only, meaning Homebrew deliberately does not symlink it into your PATH or register it with the system, because it can conflict with other Java versions.

That is why you can brew install openjdk, then run java -version and see a completely different JDK — or none at all. The install prints caveats telling you how to wire it up. To register the Homebrew JDK so macOS tooling finds it:

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

And to put it on your PATH:

echo 'export PATH="/opt/homebrew/opt/openjdk/bin:$PATH"' >> ~/.zshrc

For a specific version like brew install openjdk@17, substitute openjdk@17 in both paths. The point about the Homebrew java flow is that installing it is not the same as using it — the symlink and PATH steps are what actually make it the running JDK.

Version managers add another layer

If you install Java with Homebrew and use a version manager like SDKMAN!, jenv, or asdf, you now have yet another authority deciding which JDK runs. Version managers shim the java binary and switch it per-directory or per-shell. The result is that which java may point into ~/.sdkman/ or ~/.jenv/ rather than any of the locations above, and it can change as you cd between projects.

This is convenient and also exactly how stale JDKs hide. A version manager happily keeps a three-year-old, end-of-life Java release installed and selectable forever. List what each manager has:

sdk list java        # SDKMAN!
jenv versions        # jenv
asdf list java       # asdf

Why "where is Java" is a security question

Every JDK on a machine is code that can execute, and old JDKs accumulate known vulnerabilities. Oracle ships quarterly Critical Patch Updates for the JDK, and OpenJDK distributions follow with their own security releases; a JDK you stopped updating is a growing pile of unpatched CVEs. If a build server runs three JDKs and only one gets patched, the other two are latent risk — and the one your CI actually invokes might be the neglected one.

The discipline is straightforward once you can enumerate them: find every JDK (the commands above), record its exact version and vendor, drop anything past its end-of-life, and keep the rest current. On CI hosts especially, pin JAVA_HOME explicitly so builds cannot silently fall back to whatever old JDK happens to be first on the PATH.

The same reasoning extends to what your applications bundle. A container image or fat JAR often ships its own JDK or JRE, and that copy needs patching too — it will not update just because you updated the JDK on your laptop. Scanning your build artifacts with software composition analysis surfaces the Java runtime version baked into an image, which is frequently older than anything on the host that built it. For hardening the applications running on those JDKs, the Java security best practices guide covers the layer above the runtime.

FAQ

Where does Homebrew install Java on a Mac?

On Apple Silicon, under /opt/homebrew/opt/openjdk (with the real files in /opt/homebrew/Cellar/openjdk/); on Intel Macs, under /usr/local/opt/openjdk. It is keg-only, so Homebrew does not add it to your PATH or register it with the system automatically — you have to symlink and export it yourself.

Why does java -version show a different version than I just installed?

Because installing Java and selecting it are separate steps. java -version reflects whatever the PATH (or a version manager's shim) resolves, not necessarily your newest install. Homebrew's keg-only JDKs and version-manager shims are the usual culprits. Check which java to see the actual binary in use.

How do I list every Java installed on macOS?

Run /usr/libexec/java_home -V. It prints all JDKs registered with the system, their versions, and paths. Add any version-manager listings (sdk list java, jenv versions) to catch JDKs the system helper does not know about.

Is having multiple JDKs installed a security risk?

It can be, if the extra ones go unpatched. Each JDK is executable code carrying whatever known vulnerabilities existed at its release. Old, end-of-life JDKs left installed and selectable are the risk — inventory them, remove what you do not need, and keep the rest current.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.