Configuring the JDK Version in a DevContainer
A JVM project must compile against a known JDK, and the editor must analyze against the same one. This page pins the JDK via the Java Feature and points the Java language server at it, so the build and the editor never disagree about the Java version.
Prerequisites
You need a Java devcontainer and the target JDK version.
- The Java Feature available.
- The JDK version your project targets.
- The Java extension pack in the container.
Step-by-Step Implementation
- Pin the JDK via the Feature.
{
"features": { "ghcr.io/devcontainers/features/java:1": { "version": "21" } },
"remoteUser": "vscode"
}
- Point the language server at that JDK.
{ "customizations": { "vscode": { "settings": {
"java.jdt.ls.java.home": "/usr/local/sdkman/candidates/java/current"
} } } }
- Configure runtimes if you target multiple JDKs.
{ "customizations": { "vscode": { "settings": {
"java.configuration.runtimes": [ { "name": "JavaSE-21", "path": "/usr/local/sdkman/candidates/java/current", "default": true } ]
} } } }
- Verify the versions match.
java -version # matches the pinned Feature and the LS java.home
Common Pitfalls
JDK mismatches come from an unpinned Feature or a wrong java.home.
| Symptom | Root Cause | Remediation |
|---|---|---|
| Editor errors differ from build | LS on a different JDK | Set java.jdt.ls.java.home to the JDK |
| Wrong Java version at build | Feature version unpinned | Pin the Java Feature version |
| Multi-module targets differ | No runtimes config | Configure java.configuration.runtimes |
| Preview features fail | JDK too old | Pin a newer JDK version |
Conclusion
Pin the JDK on the Java Feature so the build compiles against a known version, and point the language server's java.home at the same JDK so the editor analyzes it too. When both use one Java, the editor's verdict matches the build's.
FAQ
How do I pin the JDK version?
Set the version on the Java Feature (ghcr.io/devcontainers/features/java with "version": "21"). Every rebuild then installs that exact JDK, so the build compiles against a known Java version rather than whatever happens to be installed.
Why does the editor use a different Java than my build?
The Java language server has its own java.home setting. If it isn't pointed at the container's JDK, it analyzes against a different Java. Set java.jdt.ls.java.home (and java.configuration.runtimes) to the Feature-installed JDK so both agree.
Can I target multiple JDKs in one container?
Yes — install the JDKs you need and list them in java.configuration.runtimes, marking one default. Modules can then target different Java versions, and the language server resolves each against the correct runtime.
Related
- Up to Java & JVM DevContainer Configuration — the overview of JVM setup.
- Caching Maven and Gradle Dependencies in a DevContainer — caching the dependency store.
- Debugging Java in a DevContainer — debugging against the pinned JDK.