To change the Java version on a Mac you point JAVA_HOME at the JDK you want, usually with the built-in /usr/libexec/java_home helper or a version manager like jenv, and confirm the switch with java -version. That sounds like housekeeping, but the version you leave active is the one that runs your builds, your local services, and any tool that shells out to java — so picking it is a security choice as much as a developer-experience one.
This guide covers how to switch Java version on Mac cleanly, and where the security tradeoffs hide.
See which JDKs are already installed
macOS can hold several JDKs at once under /Library/Java/JavaVirtualMachines. List them with the helper Apple ships:
/usr/libexec/java_home -V
You will get output like this:
Matching Java Virtual Machines (3):
21.0.3 (arm64) "Eclipse Adoptium" - "OpenJDK 21.0.3"
17.0.11 (arm64) "Eclipse Adoptium" - "OpenJDK 17.0.11"
11.0.23 (arm64) "Homebrew" - "OpenJDK 11.0.23"
That list is your first security check. If a JDK here is several patch releases behind, it is carrying known CVEs in the runtime itself. Note the versions before you decide which one to activate.
Change the Java version for the current shell
The fastest way to do a mac change java version for one terminal session is to set JAVA_HOME from the helper:
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
java -version
The -v 17 argument asks for the newest installed 17.x. To make it stick across restarts, add that export line to ~/.zshrc (or ~/.bash_profile if you still use bash). Reload with source ~/.zshrc.
Always finish with java -version and read the output. The number it prints is the truth; what you think you set is not.
How to switch Java version on Mac per project with jenv
Hardcoding one JAVA_HOME breaks the moment you work on two apps that need different JDKs. That is what jenv solves, and it is the cleanest answer to how to switch Java version on Mac on a per-directory basis.
brew install jenv
echo 'eval "$(jenv init -)"' >> ~/.zshrc
source ~/.zshrc
Register each JDK you found earlier, then set a global default and per-project overrides:
jenv add /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home
jenv add /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home
jenv global 21
cd ~/work/legacy-service && jenv local 17
jenv local 17 writes a .java-version file in the project. Anyone who clones the repo and has jenv gets the same JDK, which removes a whole class of "works on my machine" build differences. This is the pattern I recommend when someone asks how to change Java version mac across several repos.
Installing a newer JDK before you switch
If the version you actually want is not in the list, install it first. Homebrew is the common route:
brew install --cask temurin@21
Prefer a build with a support lifecycle you can track — Eclipse Temurin, Amazon Corretto, or Oracle's builds. The reason is patch cadence: Long-Term Support lines like 17 and 21 receive quarterly security updates, so an LTS JDK is far easier to keep current than a short-lived feature release you have to replace every six months.
Why the active Java version is a security concern
The JDK is not just a compiler; it ships TLS stack, XML parsers, cryptography providers, and the class libraries your whole application trusts. When you learn how to switch java version mac and casually leave an old 11.0.2 or 17.0.1 active, you are running a runtime that predates fixes for issues in those components.
A few habits keep this safe:
- Run
java -versionafter every switch and treat an unexpectedly old build as a finding, not a shrug. - Keep each installed line patched — reinstalling
temurin@17periodically pulls the latest patch release. - Remove JDKs you no longer use from
/Library/Java/JavaVirtualMachinesso you cannot accidentally activate an unpatched one.
Your local runtime is only half the story. The Java libraries your project pulls in — Jackson, Log4j, Spring — carry their own vulnerabilities regardless of which JDK is active. An SCA tool such as Safeguard can flag those transitive dependency risks that no amount of JAVA_HOME tuning will fix. For a concrete example of a library-level issue, see our Jackson databind security guide.
A repeatable workflow
Put it together and switching becomes routine:
/usr/libexec/java_home -Vto inventory installed JDKs and spot stale ones.brew install --cask temurin@<version>if the one you need is missing.jenv global <version>for your default,jenv local <version>per project.java -versionto confirm, every time.
That is the whole loop for how to change java version mac, whether you switch once a month or twenty times a day.
FAQ
How do I change the Java version on Mac permanently?
Set JAVA_HOME in your shell profile (~/.zshrc) using export JAVA_HOME=$(/usr/libexec/java_home -v <version>), or use jenv global <version>. Both persist across terminal restarts; jenv is better if you juggle multiple JDKs.
Why does java -version still show the old version after I switch?
Your shell profile is probably exporting a different JAVA_HOME, or you are calling a java binary earlier on your PATH (for example a Homebrew symlink). Check with which java and echo $JAVA_HOME, then reconcile them.
Is it safe to keep several Java versions installed?
Yes, as long as each one is patched. The risk is not having multiples — it is accidentally activating a JDK that is months behind on security updates. Reinstall periodically and remove versions you no longer need.
Does the JDK version affect my application's security?
Absolutely. The JDK provides TLS, cryptography, and XML parsing your app relies on, so an out-of-date runtime carries unpatched vulnerabilities. Prefer LTS lines (17, 21) that get regular quarterly security releases.