Install JDK

Su Suriya Ravichandran Updated 14 Nov 2026
6 min read ·Lesson 30 of 133

This lesson installs a Java Development Kit on Windows, macOS, and Linux, then configures the PATH and JAVA_HOME environment variables that tools use to find it. The examples use Eclipse Temurin, but the steps are the same for any OpenJDK distribution. Replace the version number (25 below) with the current LTS you want.

Windows

Option 1: Installer (.msi)

  1. Go to adoptium.net, choose the latest LTS, Windows, x64 (or aarch64 on ARM devices), and download the .msi file.
  2. Run the installer. On the Custom Setup screen, enable:
    • Add to PATH
    • Set JAVA_HOME variable
  3. Finish the installation.
  4. Open a new terminal window. Terminals that were already open keep the old environment variables and will not see the change.

Option 2: winget

Windows 10 and 11 include the winget package manager. In PowerShell or Command Prompt:

winget search Temurin
winget install EclipseAdoptium.Temurin.25.JDK

winget search lists the available package IDs; use the ID that matches the version you want. Open a new terminal afterward.

Verify

java -version
javac -version
echo %JAVA_HOME%

In PowerShell, use echo $env:JAVA_HOME for the last line.

macOS

Option 1: Installer (.pkg)

  1. Download the macOS .pkg from adoptium.net. Choose aarch64 for Apple Silicon (M-series) Macs and x64 for Intel Macs. Check under Apple menu → About This Mac if unsure.
  2. Run the installer. The JDK is placed in /Library/Java/JavaVirtualMachines/.

macOS ships a /usr/bin/java stub that automatically uses the newest JDK in that folder, so java and javac work in a new terminal without editing PATH.

Option 2: Homebrew

brew install --cask temurin

This installs the latest Temurin release. Specific versions are available as separate casks, for example brew install --cask temurin@21.

Setting JAVA_HOME on macOS

Many build tools expect JAVA_HOME. macOS provides a helper that prints the path of an installed JDK:

/usr/libexec/java_home            # newest installed JDK
/usr/libexec/java_home -v 21      # a specific version
/usr/libexec/java_home -V         # list all installed JDKs

Add this line to ~/.zshrc (zsh is the default shell on current macOS):

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

Then reload the configuration and verify:

source ~/.zshrc
echo $JAVA_HOME
java -version

Linux

Debian and Ubuntu (apt)

sudo apt update
apt search openjdk | grep jdk          # see which versions your release offers
sudo apt install openjdk-21-jdk        # substitute the version listed

Install the package ending in -jdk, not -jre. The -jdk-headless variant omits GUI libraries and suits servers.

Distribution repositories may not carry the newest release. For the latest Temurin on Debian/Ubuntu, Adoptium publishes its own apt repository; follow the instructions at adoptium.net/installation.

Fedora, RHEL, Rocky Linux (dnf)

dnf search openjdk
sudo dnf install java-21-openjdk-devel

On Red Hat–based systems, the -devel package contains javac; the package without -devel contains only the runtime.

Arch Linux

sudo pacman -S jdk-openjdk

Switching between installed versions

Debian/Ubuntu and Fedora use the alternatives system to choose which installed JDK the java command runs:

sudo update-alternatives --config java    # Debian/Ubuntu
sudo alternatives --config java           # Fedora/RHEL

Choose the number of the version you want. Repeat for javac to keep them matched.

Setting JAVA_HOME on Linux

Find where the JDK is installed:

readlink -f "$(which javac)"
# /usr/lib/jvm/java-21-openjdk-amd64/bin/javac

JAVA_HOME is the directory above bin. Add to ~/.bashrc (or ~/.zshrc):

export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export PATH="$JAVA_HOME/bin:$PATH"

Reload with source ~/.bashrc.

SDKMAN! (macOS, Linux, WSL)

SDKMAN! installs and switches between many JDK versions and vendors without administrator rights. It is popular with developers who work on several projects.

curl -s "https://get.sdkman.io" | bash
# open a new terminal, then:
sdk list java                  # shows available versions and vendor identifiers
sdk install java <identifier>  # e.g. an identifier ending in -tem for Temurin
sdk use java <identifier>      # use a version in the current terminal only
sdk default java <identifier>  # make it the default for new terminals

Identifiers combine a version and a vendor code, such as -tem for Temurin. Copy one exactly from the sdk list java output. SDKMAN! sets JAVA_HOME and PATH automatically.

Manual Archive Installation (Any OS)

When you cannot use an installer or lack administrator rights:

  1. Download the .zip (Windows) or .tar.gz (macOS/Linux) from the vendor.
  2. Extract it to a folder you control, such as C:\dev\jdk-25 or ~/jdks/jdk-25.
  3. Set JAVA_HOME to that folder and add JAVA_HOME/bin to the PATH as shown below.

Nothing else is required. A JDK is self-contained, and removing it is simply deleting the folder.

PATH and JAVA_HOME Explained

VariablePoints toUsed by
PATHThe JDK's bin directory (among many others)Your shell, to find java, javac, jshell when you type them
JAVA_HOMEThe JDK's root directory (the one containing bin)Maven, Gradle, Tomcat, IDEs, and scripts that need to locate the JDK

JAVA_HOME must point to the JDK root, not to bin. A common error is setting it to .../jdk-25/bin, which makes tools look for .../jdk-25/bin/bin/java and fail.

Setting them manually on Windows

  1. Open the Start menu, search Edit the system environment variables, and open it.
  2. Click Environment Variables.
  3. Under User variables (or System variables for all users), click New:
    • Name: JAVA_HOME
    • Value: C:\Program Files\Eclipse Adoptium\jdk-25.0.1.8-hotspot (your actual folder)
  4. Select the Path variable, click Edit, click New, and add %JAVA_HOME%\bin. Move it above any older Java entries.
  5. Click OK on every dialog, then open a new terminal.

Referencing %JAVA_HOME%\bin in Path, rather than repeating the full folder, means only JAVA_HOME needs changing when you upgrade.

Troubleshooting

SymptomCauseFix
'java' is not recognized / command not foundJDK bin not on PATH, or terminal opened before installationOpen a new terminal; check PATH
java -version shows an old versionAn older Java appears earlier on PATHMove the new JDK's bin higher; on Linux use update-alternatives
javac not found but java worksOnly a runtime installed, or wrong package (-jre)Install the full JDK (-jdk / -devel)
java and javac report different versionsPATH mixes two installationsEnsure both come from the same bin directory
Maven/Gradle: JAVA_HOME is not defined correctlyJAVA_HOME unset, or pointing at binSet it to the JDK root
UnsupportedClassVersionError when runningClass compiled with a newer JDK than the one running itRun with the newer JDK, or compile with --release <older version>

The last error deserves explanation. Each Java version writes a version number into the .class files it produces. A JVM refuses to load classes from a newer version than itself, because they may use bytecode features it does not understand. javac --release 17 App.java compiles code that can run on Java 17 and later, even when using a newer JDK, and also checks that the code uses only APIs available in Java 17.

Final Check

java -version
javac -version
jshell --version

All three should report the same version. Then start JShell and evaluate an expression:

$ jshell
|  Welcome to JShell -- Version 25.0.1
|  For an introduction type: /help intro

jshell> 2 + 3 * 4
$1 ==> 14

jshell> /exit
|  Goodbye

If these commands work, the JDK is correctly installed and ready for the rest of the tutorial.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about Install JDK and get answers drawn from it.

Signed-in readers only.