Wrong JAVA_HOME / JDK Version in CI - Pin the Toolchain
Your build is running on a different JDK than you think. JAVA_HOME or PATH resolves an interpreter you did not intend, so compiles, tests, or tools behave unexpectedly.
What this error means
Code that builds locally fails in CI with a version-specific error, or java -version / mvn -version prints a JDK other than what you configured. Subtle issues (different default GC, API availability) trace back to the wrong JDK.
$ java -version
openjdk version "11.0.22" 2024-01-16
# but the project expects 21 - JAVA_HOME points at the wrong JDKCommon causes
Image default JDK, not the one you set
The runner ships several JDKs. Without explicitly setting JAVA_HOME/PATH, the build inherits the image default, which may not match your project.
setup-java skipped or shadowed
If actions/setup-java did not run, or a later step changed PATH/JAVA_HOME, the JDK in use is not the one you configured.
How to fix it
Pin the JDK and assert it
Set up the exact JDK and verify it before building.
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
- run: |
java -version
echo "JAVA_HOME=$JAVA_HOME"
mvn -B -versionUse build-tool toolchains for the compile JDK
Decouple the compile JDK from the ambient JAVA_HOME with Maven/Gradle toolchains so the build is reproducible regardless of the runner default.
// Gradle build.gradle.kts
java {
toolchain { languageVersion = JavaLanguageVersion.of(21) }
}How to prevent it
- Always pin the JDK in CI; never rely on the image default.
- Add a
java -version/mvn -versionassertion step early. - Use Gradle/Maven toolchains so the compile JDK is explicit.