Installing a JDK, and JAVA_HOME
Installing one, then proving which one you got — and the two variables that decide it.
Installing a JDK is easy. Knowing which one you just installed is the part that matters, because a machine can have four and the one that runs is decided by something you have not looked at.
Installing
macOS — Homebrew is the least trouble: brew install --cask temurin. Installers from the distribution's site work too.
Linux — your package manager (apt install temurin-21-jdk with Adoptium's repository, or your distribution's openjdk-21-jdk), or unpack a tarball anywhere and point at it.
Windows — the .msi from the distribution, which offers to set JAVA_HOME and PATH for you. Let it.
Any of them — a version manager (SDKMAN! on Unix, jabba, or your IDE's downloader) if you expect to switch between versions. Which you will, the first time you work on two projects.
The install is not the lesson. This is:
Prove what you got
Two commands, and they answer different questions:
which java # WHERE the java that runs comes from
java -version # WHAT version that one isRun both, every time you are surprised. java -version alone is the command people run and it cannot tell you that there are three other JDKs on the machine.
$ which java
/usr/local/bin/java
$ java -version
openjdk version "21.0.12" 2026-07-21 LTS
OpenJDK Runtime Environment Temurin-21.0.12+8 (build 21.0.12+8-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.12+8 (build 21.0.12+8-LTS, mixed mode, sharing)And check the compiler separately, because it is a different binary and can be a different version:
javac -versionThe two variables
PATH is a list of directories. When you type java, the shell walks it in order and runs the first match. That is what which is reporting.
JAVA_HOME points at the root of a JDK installation — not at the binary:
JAVA_HOME=/usr/lib/jvm/temurin-21 # yes: the directory containing bin/, lib/
JAVA_HOME=/usr/lib/jvm/temurin-21/bin/java # noPATH is for the shell. JAVA_HOME is for other programs — Maven, Gradle, application servers, scripts — which need more than the launcher: they need javac, the libraries, the whole installation.
They can disagree, and that is the confusing afternoon above. Set both, to the same JDK:
export JAVA_HOME=/usr/lib/jvm/temurin-21
export PATH="$JAVA_HOME/bin:$PATH"Putting $JAVA_HOME/bin first is what makes that JDK win over anything installed elsewhere.
Those two lines belong in your shell's startup file (~/.zshrc, ~/.bashrc) — export in a terminal lasts only as long as that terminal.
What you actually installed
A JDK is a directory. Look inside bin/ and you find about thirty programs:
jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps
jfr jhsdb jimage jinfo jlink jmap jmod jpackage jps jrunscript jshell
jstack jstat jstatd jwebserver keytool rmiregistry serialverMost you will never type. Six are worth knowing the names of now, so that when a lesson later says "run jcmd", it is a tool you have rather than something to install:
| Tool | For |
|---|---|
java | run |
javac | compile |
jshell | try a line without a class |
javap | see what javac produced |
jcmd | ask a running JVM questions |
jstack | what every thread is doing right now |
The last two are diagnostics, and the fact that they ship with the platform is unusual and genuinely useful. You do not install anything to debug a production Java process.
Try it yourself
Establish the truth about your machine
which javaandjava -version. Do they agree with what you think you installed?javac -version. Same major version?echo $JAVA_HOME. Is it set, and does it point at a directory containingbin/?ls $JAVA_HOME/bin | wc -l. How many tools did you get?
If something is wrong
JAVA_HOME empty: set it, in your shell startup file, and add $JAVA_HOME/bin to the front of PATH.
java and javac differ: which -a java and which -a javac list every match in PATH order, not just the winner. That shows you the competing installations.
which java points somewhere you did not install: on macOS /usr/bin/java is a stub that finds a JDK for you and is often not the one you want. Putting $JAVA_HOME/bin first in PATH overrides it.