From be70cc24b66b66198daeb3b3f31666c3b081ea67 Mon Sep 17 00:00:00 2001 From: Zach Klippenstein Date: Tue, 18 Aug 2026 11:41:21 -0700 Subject: [PATCH] Compile build-logic with JDK 17 so the build runs on a JDK 17 daemon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build-logic is on the buildscript classpath, so the Gradle daemon loads its classes directly. Compiling it with the jdk-toolchain (21) meant the daemon itself had to be JDK 21, and building on a stock JDK 17 environment failed with: Could not resolve project :build-logic. > Dependency requires at least JVM runtime version 21. This build uses a Java 17 JVM. The 21 was inherited from the libraries' toolchain, which conflated two different things: the JDK the libraries compile with (a real Gradle toolchain, forked by the daemon) and the JDK the daemon must be able to load. Only the latter constrains JAVA_HOME. Split them with a new jdk-buildLogic version, set to 17 — the floor Gradle 9 and AGP 8 already require. The libraries still compile with the JDK 21 toolchain, so parity with android-register's compile JDK is preserved, and published bytecode is unchanged (jdk-target stays at 11). Also document the three JDK versions in CONTRIBUTING.md, which previously didn't mention any JDK requirement. Co-Authored-By: Claude --- CONTRIBUTING.md | 20 ++++++++++++++++++++ build-logic/build.gradle.kts | 4 +++- gradle/libs.versions.toml | 7 +++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7725594c98..4e0021960a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,6 +9,26 @@ and style in order to keep the code as readable as possible. Please also make sure your code compiles by running `./gradlew clean build`. If you're using IntelliJ IDEA, we use [Square's code style definitions][2]. +Building +-------- + +You need **JDK 17 or newer** to run Gradle, and **JDK 21 installed** for the build to compile +against. + +The build uses three separate JDK versions, configured in `gradle/libs.versions.toml`: + +| Version | Purpose | +|---|---| +| `jdk-target` (11) | Bytecode version published to consumers | +| `jdk-toolchain` (21) | JDK the libraries are compiled with, via a Gradle toolchain | +| `jdk-buildLogic` (17) | JDK `build-logic` is compiled with — the floor for your Gradle daemon | + +Gradle forks a JDK 21 toolchain for compilation, so your `JAVA_HOME` does not need to be 21 — but a +JDK 21 must be installed somewhere Gradle can [auto-detect][3] it. If you see +`Cannot find a Java installation ... matching languageVersion=21`, install a JDK 21. + + [3]: https://docs.gradle.org/current/userguide/toolchains.html#sec:auto_detection + Before your code can be accepted into the project you must also sign the [Individual Contributor License Agreement (CLA)][1]. diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 132fb57136..2c866a01a3 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -81,5 +81,7 @@ dependencies { } java { - toolchain.languageVersion.set(JavaLanguageVersion.of(libs.versions.jdk.toolchain.get())) + // Deliberately not jdk-toolchain: build-logic is on the buildscript classpath, so the Gradle + // daemon loads these classes directly and can't read bytecode newer than its own JDK. + toolchain.languageVersion.set(JavaLanguageVersion.of(libs.versions.jdk.buildLogic.get())) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8915691fef..c514276bbd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,8 +6,15 @@ compileSdk = "36" minSdk = "24" targetSdk = "33" +# The bytecode version published to consumers. jdk-target = "11" +# The JDK used to compile the libraries, via a Gradle toolchain. Matches android-register's compile +# JDK. Gradle forks this JDK for compilation, so it does not constrain the daemon's JDK. jdk-toolchain = "21" +# The JDK used to compile build-logic. Unlike the above, this *does* constrain the daemon: build-logic +# is on the buildscript classpath, so the daemon must be able to load its bytecode. Keep it at the +# floor Gradle and AGP already require (17) so the build works on a stock JDK 17 environment. +jdk-buildLogic = "17" androidx-activity = "1.11.0" androidx-appcompat = "1.7.1"