skip to content

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?

level: middleimportance: should knowfreq 35%

answer

  1. jvmToolchain = Kotlin sugar over java.toolchain
  2. wires KotlinCompile tasks
  3. aligns jvmTarget
  4. guarantees Java+Kotlin same JDK
  5. block form sets vendor

basics

~20 s

jvmToolchain(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 lines
kotlin
kotlin {
    jvmToolchain {
        languageVersion = JavaLanguageVersion.of(17)
        vendor = JvmVendorSpec.ADOPTIUM
    }
}
// vs pure-Java module:
java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }

go deeper

for a junior

Know jvmToolchain() is the Kotlin one-liner for selecting the compile JDK.

for a middle

Explain it sets the Java toolchain AND wires Kotlin compile tasks + jvmTarget, ensuring alignment.

for a senior

Compare with the raw java.toolchain block, note Kotlin follows an existing Java toolchain, and when to use each.

for a principal

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).

context