How to Install Java (OpenJDK) on Windows Server 2022

Java remains one of the most widely used runtime platforms on Windows Server, powering enterprise applications, middleware (Apache Tomcat, JBoss/WildFly, WebLogic), analytics platforms, and a broad range of internal tools. Windows Server 2022 does not ship with Java pre-installed, so every Java workload begins with a manual JDK installation. This guide covers downloading and installing Adoptium Temurin OpenJDK, setting environment variables, verifying the installation, managing heap size, running side-by-side JDK versions, and installing Maven for build automation.

Choosing a Java Distribution

Oracle’s commercial JDK requires a license for production use. For most server workloads on Windows Server 2022, use one of the freely licensed OpenJDK builds:

  • Eclipse Temurin (Adoptium)https://adoptium.net/ — the most widely used, TCK-verified, community-supported OpenJDK build. Recommended for most scenarios.
  • Microsoft Build of OpenJDKhttps://learn.microsoft.com/en-us/java/openjdk/ — Microsoft-maintained build with long-term support, optimized for Azure.
  • Amazon Corretto — Amazon’s free, production-ready OpenJDK distribution with multi-year support patches.
  • Azul Zulu — A commercially backed OpenJDK build with extended support options.

This guide uses Eclipse Temurin (Adoptium) as it is the most portable and widely adopted open distribution.

Downloading Temurin OpenJDK

Download the installer or zip from the Adoptium API or the website. For automation, use the Adoptium API to fetch the latest LTS release:

# Download Temurin JDK 21 (LTS) MSI installer for Windows x64
$url = "https://api.adoptium.net/v3/installer/latest/21/ga/windows/x64/jdk/hotspot/normal/eclipse"
Invoke-WebRequest -Uri $url -OutFile "C:Installerstemurin-21-jdk-windows-x64.msi"

# Alternatively, download the zip (no installer, manual setup)
$zipUrl = "https://api.adoptium.net/v3/binary/latest/21/ga/windows/x64/jdk/hotspot/normal/eclipse"
Invoke-WebRequest -Uri $zipUrl -OutFile "C:Installerstemurin-21-jdk-windows-x64.zip"

Installing Temurin JDK via MSI

The MSI installer supports silent installation and can automatically set JAVA_HOME and add the JDK to the system PATH. Run the following command in an elevated PowerShell or CMD session:

# Silent install — sets JAVA_HOME and updates PATH automatically
msiexec.exe /i "C:Installerstemurin-21-jdk-windows-x64.msi" `
    /quiet `
    /qn `
    ADDLOCAL="FeatureMain,FeatureEnvironment,FeatureJarFileRunWith,FeatureJavaHome" `
    INSTALLDIR="C:Program FilesEclipse Adoptiumjdk-21"

The ADDLOCAL parameters control which features are installed:

  • FeatureMain — the JDK binaries (required)
  • FeatureEnvironment — adds %JAVA_HOME%bin to the system PATH
  • FeatureJarFileRunWith — associates .jar files with java.exe
  • FeatureJavaHome — sets the JAVA_HOME system environment variable

Manual Installation from ZIP

If you prefer to control the install location precisely (or need to install multiple JDKs side-by-side), extract the zip and configure environment variables manually:

# Extract to a versioned directory
Expand-Archive -Path "C:Installerstemurin-21-jdk-windows-x64.zip" `
    -DestinationPath "C:Java"

# Rename the extracted folder for clarity
Rename-Item -Path "C:Javajdk-21.0.3+9" -NewName "jdk-21"

# Verify the structure
dir "C:Javajdk-21binjava.exe"

Setting JAVA_HOME and PATH Environment Variables

Java tools (Maven, Gradle, Ant, many application servers) rely on the JAVA_HOME environment variable to locate the JDK. It must point to the JDK root directory (not the bin subdirectory). Set it at the machine level so all services and users inherit it:

# Set JAVA_HOME (machine-level, persists across reboots)
[System.Environment]::SetEnvironmentVariable(
    "JAVA_HOME",
    "C:Javajdk-21",
    [System.EnvironmentVariableTarget]::Machine
)

# Add %JAVA_HOME%bin to PATH
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::Machine)
if ($currentPath -notlike "*C:Javajdk-21bin*") {
    [System.Environment]::SetEnvironmentVariable(
        "PATH",
        "C:Javajdk-21bin;$currentPath",
        [System.EnvironmentVariableTarget]::Machine
    )
}

# Verify in the current session (requires re-reading environment)
$env:JAVA_HOME = "C:Javajdk-21"
$env:PATH = "C:Javajdk-21bin;$env:PATH"

You can also set environment variables through System Properties:

  1. Right-click This PC > Properties
  2. Click Advanced system settings
  3. Click Environment Variables
  4. Under System variables, click New — add JAVA_HOME = C:Javajdk-21
  5. Edit the Path variable and add %JAVA_HOME%bin at the top
# Equivalent via cmd (requires admin)
setx JAVA_HOME "C:Javajdk-21" /M
setx PATH "%JAVA_HOME%bin;%PATH%" /M

Verifying the Java Installation

Open a new command prompt or PowerShell window (environment variable changes are not picked up in existing sessions) and verify:

java -version
javac -version
echo %JAVA_HOME%
where java

Expected output from java -version:

openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9)
OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9, mixed mode, sharing)

Running JAR Files

An executable JAR file packages a Java application with a manifest that specifies the entry-point class. Run a JAR as follows:

# Run an executable JAR
java -jar "C:Appsmyapp.jar"

# Run with a specific classpath
java -cp "C:libs*;C:Appsmyapp.jar" com.example.Main

# Pass JVM system properties
java -Dconfig.file="C:Configapp.properties" -jar "C:Appsmyapp.jar"

# Run in the background (detach from console)
Start-Process -FilePath "java" `
    -ArgumentList "-jar C:Appsmyapp.jar" `
    -WindowStyle Hidden `
    -RedirectStandardOutput "C:Logsmyapp.log" `
    -RedirectStandardError "C:Logsmyapp-error.log"

JVM Heap Size Configuration

By default, Java sizes the heap based on available system memory (typically 25% of RAM for initial heap, 25-50% for max heap in modern JVMs). For server workloads, set these explicitly to avoid unpredictable behavior:

# -Xms: initial heap size  -Xmx: maximum heap size
java -Xms512m -Xmx2g -jar "C:Appsmyapp.jar"

# For large enterprise apps (e.g., Tomcat, JBoss)
java -Xms2g -Xmx8g -jar "C:Appsserver.jar"

# Modern JVM: use G1 GC (default in Java 9+) with explicit region size
java -Xms4g -Xmx16g -XX:+UseG1GC -XX:G1HeapRegionSize=16m -jar myapp.jar

# Print GC activity to help tune heap size
java -Xms1g -Xmx4g -verbose:gc -Xlog:gc*:file=C:Logsgc.log:time,uptime:filecount=5,filesize=20m -jar myapp.jar

For Windows Server deployments where the Java process runs as a Windows service (via Procrun/Tomcat Service or NSSM), JVM options are typically configured in the service configuration rather than at the command line. See the Apache Tomcat article in this series for the CATALINA_OPTS approach.

Managing Multiple JDK Versions

Many server environments run multiple Java applications requiring different JDK versions (e.g., a legacy application on Java 8, a current application on Java 17, and a greenfield project on Java 21). The recommended approach on Windows Server is to install each JDK to a versioned directory and switch JAVA_HOME per-session or per-service.

# Install JDK 8, 17, and 21 to separate directories
# C:Javajdk-8
# C:Javajdk-17
# C:Javajdk-21

# Switch active JDK in PowerShell session
function Use-Java($version) {
    $javaHome = "C:Javajdk-$version"
    if (-not (Test-Path $javaHome)) { Write-Error "JDK $version not found"; return }
    $env:JAVA_HOME = $javaHome
    $env:PATH = "$javaHomebin;" + ($env:PATH -replace [regex]::Escape("C:Javajdk-[^;]+\bin;"), "")
    java -version
}

# Usage
Use-Java 17
Use-Java 21

jenv-win is a Windows port of the Unix jenv tool. Install it via Scoop or manually, then register your JDK installations:

# Install Scoop first (https://scoop.sh), then jenv
scoop install jenv

# Add installed JDKs
jenv add "C:Javajdk-8"
jenv add "C:Javajdk-17"
jenv add "C:Javajdk-21"

# List registered JDKs
jenv versions

# Set global default
jenv global 21

# Set local (directory-specific) version — writes .java-version file
jenv local 17

Installing Apache Maven

Maven is the most widely used Java build and dependency management tool. Download the binary zip from https://maven.apache.org/download.cgi and install manually:

# Download Maven 3.9.x
$mavenVersion = "3.9.6"
Invoke-WebRequest `
    -Uri "https://dlcdn.apache.org/maven/maven-3/$mavenVersion/binaries/apache-maven-$mavenVersion-bin.zip" `
    -OutFile "C:Installersapache-maven-$mavenVersion-bin.zip"

# Extract
Expand-Archive -Path "C:Installersapache-maven-$mavenVersion-bin.zip" -DestinationPath "C:Maven"

# Set MAVEN_HOME (or M2_HOME — Maven uses both)
[System.Environment]::SetEnvironmentVariable("MAVEN_HOME", "C:Mavenapache-maven-$mavenVersion", "Machine")
[System.Environment]::SetEnvironmentVariable("M2_HOME", "C:Mavenapache-maven-$mavenVersion", "Machine")

# Add to PATH
$path = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
[System.Environment]::SetEnvironmentVariable("PATH", "$path;C:Mavenapache-maven-$mavenVersionbin", "Machine")

# Verify
mvn --version

Expected output:

Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: C:Mavenapache-maven-3.9.6
Java version: 21.0.3, vendor: Eclipse Adoptium, runtime: C:Javajdk-21
Default locale: en_US, platform encoding: UTF-8
OS name: "windows server 2022", version: "10.0", arch: "amd64", family: "windows"

Java in the Windows Registry

Installers (MSI-based JDK installs and legacy Sun/Oracle JREs) register the Java installation in the Windows Registry. Applications can use these keys to locate Java without relying on PATH:

# Check registry for installed JDKs/JREs
Get-ChildItem "HKLM:SOFTWAREJavaSoftJDK"
Get-ChildItem "HKLM:SOFTWAREJavaSoftJava Runtime Environment"

# Read the current version and home path
$jdkKey = "HKLM:SOFTWAREJavaSoftJDK"
$currentVersion = (Get-ItemProperty $jdkKey).CurrentVersion
$javaHome = (Get-ItemProperty "$jdkKey$currentVersion").JavaHome
Write-Host "Current JDK: $currentVersion at $javaHome"

JDK Update Policy and Long-Term Support

For production Windows Server deployments, always use an LTS (Long-Term Support) release of OpenJDK. As of 2024-2026, the active LTS versions are Java 8 (extended support via Temurin/Corretto), Java 11, Java 17, and Java 21. Non-LTS versions (9, 10, 12–16, 18–20, 22–23) receive only 6 months of updates before reaching end-of-life.

To check for available updates and download the latest patch release:

# Query Adoptium API for the latest Java 21 LTS release info
$apiResponse = Invoke-RestMethod `
    -Uri "https://api.adoptium.net/v3/info/release_names?release_type=ga&version=%5B21%2C22%29&heap_size=normal&jvm_impl=hotspot&vendor=eclipse"

$apiResponse.releases | Select-Object -First 5

For enterprise environments where servers are not internet-connected, download JDK updates to an internal file server and distribute them via a script, SCCM/Intune, or Ansible.