SonarSource/sonarqube · error · GradleException
JDK 21+ is required to perform this build. It's currently ${
Error message
JDK 21+ is required to perform this build. It's currently ${java.home}. What it means
The root build.gradle enforces a minimum JDK version: if the JVM running Gradle (JavaVersion.current()) is not compatible with Java 21, the build fails fast with a GradleException before configuring projects. This guards use of Java 21 language features/toolchains required by the SonarQube build.
Source
Thrown at build.gradle:20
import org.sonar.build.BlackBoxTest
import static org.gradle.api.JavaVersion.VERSION_21
plugins {
// Ordered alphabetically
id 'com.diffplug.spotless' version '8.10.1'
id 'com.gradleup.shadow' version '9.2.2' apply false
id 'com.google.protobuf' version '0.8.19' apply false
id 'com.jfrog.artifactory' version '6.0.4'
id 'com.ljarocki.parallel-zip' version '1.4.1' apply false
id "de.undercouch.download" version "5.7.0" apply false
id 'io.spring.dependency-management' version '1.1.7'
id "org.cyclonedx.bom" version "3.4.1" apply false
id 'org.sonarqube' version '7.4.0.8496'
}
if (!JavaVersion.current().isCompatibleWith(VERSION_21)) {
throw new GradleException("JDK 21+ is required to perform this build. It's currently " + System.getProperty("java.home") + ".")
}
/**
* The BOM related tasks are disabled by default, activated by:
* - running in the CI and being on a main branch or a nightly build,
* - or using '-Dbom' project property
* - or by explicit call to 'cyclonedxBom' Gradle task
*/
// Full-string regex (Groovy String.matches): must cover cyclonedxBom, cyclonedxDirectBom, and mergeCyclonedxBom.
def bomTasks = "cyclonedx(Bom|DirectBom)|mergeCyclonedxBom"
def ghBranch = System.getenv()["GITHUB_REF_NAME"]
def isMainBranch = ghBranch in ['master'] || ghBranch ==~ 'branch-[\\d.]+'
boolean enableBom = System.getenv('CI') == "true" && (isMainBranch) ||
System.getProperty("bom") != null ||
gradle.startParameter.taskNames.findAll({ it.matches(".*:($bomTasks)") })
allprojects {View on GitHub (pinned to 184c821202)
Solutions
- Install JDK 21+ and set JAVA_HOME to it before running Gradle
- Stop stale daemons with ./gradlew --stop so the new JVM is picked up
- In IntelliJ, set Settings > Build Tools > Gradle > Gradle JVM to JDK 21
- In CI, use a setup step (e.g. actions/setup-java with java-version: 21)
Example fix
// before export JAVA_HOME=/usr/lib/jvm/java-17-openjdk // after export JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew --stop && ./gradlew build
Defensive patterns
Strategy: validation
Validate before calling
// shell: verify JDK before building java -version # must be 21+ echo "$JAVA_HOME" # must point to a JDK 21+ installation
Prevention
- Pin JAVA_HOME to JDK 21 in your shell profile and CI workflow
- Run ./gradlew --stop after switching JDKs to kill old daemons
- Set the IDE Gradle JVM to JDK 21
- Use a toolchain manager (sdkman, mise) to guarantee the right JDK
When it happens
Trigger: Running ./gradlew (any task) with JAVA_HOME or the Gradle daemon JVM pointing to JDK 17, JDK 11, or any pre-21 runtime.
Common situations: Stale JAVA_HOME after upgrading JDKs; IDE (IntelliJ) Gradle JVM configured to an older JDK; Gradle daemon started under an old JVM and reused; CI runner image without JDK 21.
Related errors
- Invalid artifactoryUrl
- ${propName} is enabled but the sonarqube-unification path is
- sonar.properties file by default must not provide any user c
- JRE files in ${jresDir} do not match jres-metadata.json (mis
- ${destinationDirectory.get()}/${archiveFileName.get()} size
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/9b081b7c211d3633.
Report an issue: GitHub.