The single most common Lab 6 / Spring Boot blocker on Windows is a broken JAVA_HOME or PATH. This guide takes you from a clean Windows install to a working mvn -version showing Java 21.
Pick your path: if you have Windows 11 (or Windows 10 with App Installer), use Path A — winget. Otherwise use Path B — manual installers.
When in doubt, start with Path A. Jump to verification at the end of either path.
java -version
# openjdk version "21.0.x" 2024-xx-xx
mvn -version
# Apache Maven 3.9.x
# Java version: 21.0.x, vendor: Eclipse Adoptium
echo $env:JAVA_HOME
# C:\Program Files\Eclipse Adoptium\jdk-21.0.x.X-hotspot
If all three commands work in a fresh PowerShell window, you’re done.
Press Win, type “powershell”, right-click → Run as administrator.
winget install --id EclipseAdoptium.Temurin.21.JDK
winget install --id Apache.Maven
💡 What just happened. winget pulled the official Temurin (Eclipse Adoptium) JDK 21 and Apache Maven installers, ran them, and added the JDK to
PATHautomatically. Maven from winget does NOT setJAVA_HOMEfor you, and older Temurin installers also skip it — that’s the actual bug behind 90 % of the lab failures.
JAVA_HOME manuallyFind your exact JDK install path:
Get-ChildItem 'C:\Program Files\Eclipse Adoptium'
You’ll see something like jdk-21.0.4.7-hotspot. Copy that folder name, then:
[Environment]::SetEnvironmentVariable(
'JAVA_HOME',
'C:\Program Files\Eclipse Adoptium\jdk-21.0.4.7-hotspot',
'Machine'
)
💡 Why
'Machine'? That writes it to the system environment so every user and every shell sees it.'User'would limit it to the current Windows user — fine for a personal laptop, but inconsistent if you ever switch accounts.
bin to PATHThe winget installer usually does this, but verify:
$javaBin = "$env:JAVA_HOME\bin"
$current = [Environment]::GetEnvironmentVariable('Path', 'Machine')
if ($current -notlike "*$javaBin*") {
[Environment]::SetEnvironmentVariable(
'Path', "$current;$javaBin", 'Machine'
)
Write-Host "Added $javaBin to system PATH"
} else {
Write-Host "Already on PATH"
}
Environment variables only take effect in new processes. Skip this and java -version will keep showing the old value.
Jump to verification.
Use this if you’re on Windows 10 without winget, behind a corporate proxy, or you prefer GUI installers.
Go to https://adoptium.net/temurin/releases/?version=21&os=windows.
Pick:
.msiClick the .msi link, run it.
In the installer, on the “Custom Setup” screen, expand every option and choose “Will be installed on local hard drive” for:
Set JAVA_HOME variableJavaSoft (Oracle) registry keysAssociate .jarIf you only check JAVA_HOME, the rest still work — but ticking all three saves headaches later.
💡 Why this matters. If you don’t tick
Set JAVA_HOME variable, the installer skips it and you’ll set it by hand below. Not the end of the world — just an extra step.
Go to https://maven.apache.org/download.cgi.
Under Files, click Binary zip archive (e.g. apache-maven-3.9.9-bin.zip).
Right-click the zip → Extract All… → extract to:
C:\Program Files\Apache\
You should now have:
C:\Program Files\Apache\apache-maven-3.9.9\
├── bin\
├── boot\
├── conf\
└── lib\
💡 Why a non-user folder? Putting it in
C:\Program Files\Apache\makes it a system-wide install. If you put it underC:\Users\YourName\only your account can run it.
This is the place students get lost. Take it slow.
In the lower box (“System variables”), click New…:
JAVA_HOMEC:\Program Files\Eclipse Adoptium\jdk-21.0.4.7-hotspotC:\Program Files\Eclipse Adoptium\ and copy it.)Still in the lower box, click New… again:
MAVEN_HOMEC:\Program Files\Apache\apache-maven-3.9.9Still in the lower box, scroll to find Path, select it, click Edit…, then New and add two entries:
%JAVA_HOME%\bin
%MAVEN_HOME%\bin
Click OK on every dialog to close all of them.
⚠️ Edit “System variables”, not “User variables”. They’re two separate boxes in the same dialog. Setting them under “User variables” works for one account; “System variables” works for everyone.
Same rule as Path A — env vars only apply to new processes. Some Windows 10 builds also need a sign-out / sign-in for VS Code and IntelliJ to pick up the change.
Open a fresh PowerShell (or CMD) and run all four:
java -version
javac -version
mvn -version
echo $env:JAVA_HOME
You should see:
openjdk version "21.0.4" 2024-xx-xx
javac 21.0.4
Apache Maven 3.9.9 (...)
Maven home: C:\Program Files\Apache\apache-maven-3.9.9
Java version: 21.0.4, vendor: Eclipse Adoptium, runtime: C:\Program Files\Eclipse Adoptium\jdk-21.0.4.7-hotspot
C:\Program Files\Eclipse Adoptium\jdk-21.0.4.7-hotspot
If any of those four show a different number or fail, scroll to Troubleshooting.
This actually downloads dependencies and runs a tiny Spring Boot starter — proves Maven, Java, and your network all work together.
mkdir C:\temp\mvntest
cd C:\temp\mvntest
mvn archetype:generate -DgroupId=hello -DartifactId=hello -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
cd hello
mvn -q -DskipTests compile
If the last command finishes silently, you’re fully set up. Delete the folder when done:
cd ..\..
Remove-Item -Recurse -Force C:\temp\mvntest
'java' is not recognized as an internal or external commandPATH isn’t picking up Java.
# In a NEW PowerShell:
echo $env:Path
Look for ...jdk-21...\bin. If it’s missing, you didn’t add it (Path A step 4 or Path B step 4). If it’s there but Java still can’t be found, the folder name in JAVA_HOME is wrong — re-check with:
Get-ChildItem 'C:\Program Files\Eclipse Adoptium'
…and use the exact folder name shown.
java -version shows the wrong version (e.g. Java 8 or 17)You have another JDK earlier on PATH. Find them all:
where.exe java
If multiple lines come back, the first one wins. Remove the unwanted ones from PATH, or put %JAVA_HOME%\bin ahead of them in the system Path editor.
mvn -version shows the wrong JavaMaven uses JAVA_HOME, not PATH. So if Maven reports e.g. Java 17 while java -version reports 21, JAVA_HOME is still pointing at the old JDK.
echo $env:JAVA_HOME
# Should print the JDK 21 path, not 17
If it’s wrong, repeat Path A step 3 (or Path B step 4), then open a brand-new shell.
'mvn' is not recognized…Same as Java — %MAVEN_HOME%\bin isn’t on PATH. Re-check Path B step 4, or for Path A confirm winget actually installed Maven:
winget list Apache.Maven
PowerShell caches env vars per process. The fix is always close every shell and open a new one. If even that doesn’t work, sign out of Windows and back in.
GUIs cache JAVA_HOME from whenever they were started.
java.jdt.ls.java.home in Settings to the JDK 21 install path.mvn can’t download anythingEdit (or create) C:\Users\YourName\.m2\settings.xml:
<settings>
<proxies>
<proxy>
<id>uniproxy</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.suza.ac.tz</host>
<port>8080</port>
<username>YOURUSER</username>
<password>YOURPASS</password>
<nonProxyHosts>localhost</nonProxyHosts>
</proxy>
</proxies>
</settings>
Replace host/port with the values from the IT department.
winget itself doesn’t existYou’re on an older Windows 10 build. Either:
winget), orRight-click the .msi → Properties → tick Unblock at the bottom → Apply. Then re-run.
Bring your laptop to lab. Don’t fight env vars alone for hours — they’re a known time sink and we have a checklist that resolves 95 % of cases in 5 minutes.
| Thing | What it does | Why it’s required |
|---|---|---|
| JDK 21 | Compiles and runs Java code | Spring Boot 3 requires Java 17+; we standardise on 21 |
| Maven | Downloads dependencies, builds the project | mvn spring-boot:run is how we start the app |
JAVA_HOME |
Tells Maven (and IntelliJ, VS Code, Gradle, …) which JDK to use | Without it, Maven uses whatever java it finds on PATH — which might be Java 8 from another install |
PATH |
Tells the shell which folders to search for executables | Without %JAVA_HOME%\bin and %MAVEN_HOME%\bin on PATH, the commands don’t exist |
You only set this up once per machine. After that, every Spring Boot lab Just Works.