What does the Kotlin Gradle Plugin's `jvmToolchain()` actually do under the hood in an Android module, and how does it differ from the raw `java.toolchain` block?
answer
- jvmToolchain = Kotlin sugar over java.toolchain
- wires KotlinCompile tasks
- aligns jvmTarget
- guarantees Java+Kotlin same JDK
- block form sets vendor
basics
~20 sjvmToolchain(17) is a Kotlin-plugin convenience that sets the Java toolchain language version and wires Kotlin compile tasks to the same JDK. The raw java.toolchain block only configures Java; Kotlin needs the plugin to follow it.
solid answer
~40 s`kotlin { jvmToolchain(17) }` is sugar provided by the Kotlin Gradle Plugin. Internally it (1) configures the project's `java.toolchain.languageVersion` to 17, and (2) attaches that same resolved `JavaLauncher`/`JavaCompiler` toolchain to Kotlin compilation tasks (`KotlinCompile`) and aligns Kotlin's `jvmTarget`. Setting only `java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }` configures the Java toolchain but the Kotlin plugin will *also* honor a Java toolchain it finds — so in practice both work, but `jvmToolchain()` is the explicit, intention-revealing one-liner that also sets a sensible Kotlin jvmTarget. In Android, where most code is Kotlin, `jvmToolchain()` is the idiomatic choice; it guarantees Java (`JavaCompile`) and Kotlin (`KotlinCompile`) run on the same JDK, avoiding cross-toolchain mismatches.
code
kotlin · 8 lineskotlin {
jvmToolchain {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.ADOPTIUM
}
}
// vs pure-Java module:
java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }go deeper
Know jvmToolchain() is the Kotlin one-liner for selecting the compile JDK.
Explain it sets the Java toolchain AND wires Kotlin compile tasks + jvmTarget, ensuring alignment.
Compare with the raw java.toolchain block, note Kotlin follows an existing Java toolchain, and when to use each.
Standardize the convention module-wide; decide whether convention plugins inject jvmToolchain() across an Android codebase.
## The two surfaces ### Raw Java toolchain ```kotlin java { toolchain { languageVersion = JavaLanguageVersion.of(17) // optional: vendor, implementation } } ``` This configures only the *Java* plugin's toolchain — Gradle resolves a matching JDK and uses its `javac` for `JavaCompile` tasks. ### Kotlin convenience ```kotlin kotlin { jvmToolchain(17) } ``` Under the hood the Kotlin Gradle Plugin: 1. Sets `java.toolchain.languageVersion` to 17 (so `JavaCompile` uses JDK 17). 2. Resolves the toolchain to a `JavaLauncher`/`JavaCompiler` and assigns it to `KotlinCompile` tasks (so `kotlinc` runs on JDK 17's JVM). 3. Aligns Kotlin's `compilerOptions.jvmTarget` to a compatible value. A block form lets you set vendor too: ```kotlin kotlin { jvmToolchain { languageVersion = JavaLanguageVersion.of(17) vendor = JvmVendorSpec.AZUL } } ``` ## Why it matters in Android An AGP module typically has **both** Java and Kotlin sources. If only Java had a toolchain and Kotlin didn't follow it, you could compile Java on JDK 17 but run `kotlinc` on the daemon JDK — a mismatch. `jvmToolchain()` guarantees alignment. AGP itself reads the Java toolchain for its `JavaCompile` tasks, so once the toolchain is set, AGP, the Java plugin, and the Kotlin plugin all agree. ## Resolution & provisioning Either form triggers the same toolchain *resolution*: Gradle searches detected local JDKs and, if a resolver plugin (Foojay) is configured, downloads a matching one. The choice between the two surfaces does not change provisioning behavior. ## Takeaway Prefer `kotlin { jvmToolchain(n) }` in Android for clarity and guaranteed Java+Kotlin alignment; reach for the raw `java.toolchain` block only in pure-Java library modules with no Kotlin plugin applied.
- If you set only `java.toolchain` in a Kotlin module, will Kotlin compile on that JDK?Generally yes — the Kotlin plugin honors an existing Java toolchain — but jvmToolchain() makes the intent explicit and also sets a matching jvmTarget.
- Can you set a JDK vendor with jvmToolchain()?Yes, via the block form: `jvmToolchain { languageVersion = ...; vendor = JvmVendorSpec.AZUL }`.
saying these in an interview costs you the question
- Saying jvmToolchain() and java.toolchain are entirely unrelated — jvmToolchain configures the Java toolchain too.
- Assuming Kotlin always ignores the Java toolchain (it usually follows it).