Gradle Kotlin项目必须显式声明jvmToolchain为整数(如17),否则Kotlin编译器生成字节码可能与JDK版本不匹配,导致UnsupportedClassVersionError;需在build.gradle.kts中同时配置java.toolchain和kotlin.jvmToolchain并保持一致,且kotlin 1.9+应使用compilerOptions.jvmTarget。

Gradle Kotlin项目必须显式声明jvmToolchain
不设 jvmToolchain,Kotlin编译器默认生成的字节码可能与你本地 JDK 版本不匹配,运行时抛 UnsupportedClassVersionError。这不是警告,是硬性失败点,尤其在 CI 环境或团队协作中极易暴露。
Gradle 17+ 引入 jvmToolchain 统一管理源码兼容性、字节码目标版本、测试 JVM 和构建任务 JVM,它比旧式 sourceCompatibility/targetCompatibility 更可靠——因为后者只影响 Java 编译,对 Kotlin 编译器(kotlinc)无约束力。
-
jvmToolchain必须写在build.gradle.kts的java块内,且优先级高于kotlinOptions.jvmTarget - 若同时设了
kotlinOptions.jvmTarget,它会被jvmToolchain覆盖;但建议保留,作为显式声明和 IDE 友好提示 - 值必须是整数(如
17),不能写成"17"或JavaVersion.VERSION_17(后者仅用于旧 API) - 该配置对
compileKotlin、test、run、jar等所有 JVM 相关任务生效
build.gradle.kts 中正确写法(Kotlin DSL)
以下是最小可行配置,适用于 Kotlin/JVM 项目(非 Android):
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
kotlin {
jvmToolchain(17)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}
注意两点:
-
java.toolchain控制 Java 编译、测试 JVM、JAR 清单等;kotlin.jvmToolchain是 Kotlin 插件专用入口,二者需保持一致,否则 Gradle 会警告并取交集(通常以java.toolchain为准) -
compilerOptions.jvmTarget是 Kotlin 1.9+ 推荐写法,替代已弃用的kotlinOptions.jvmTarget - 如果项目含 Java 源码,
java.toolchain是必需项;纯 Kotlin 项目也不能省略,因为 Gradle 默认 Java 工具链为 8,会拖垮 Kotlin 编译输出
Android 项目要额外处理 kotlinOptions
Android Gradle Plugin(AGP)7.4+ 后,android.kotlinOptions 不再受 jvmToolchain 自动同步,必须手动对齐:
android {
compileSdk = 34
// ...
kotlinOptions {
jvmTarget = "17" // 字符串形式,必须与 jvmToolchain 一致
freeCompilerArgs += "-Xjvm-default=all"
}
}
kotlin {
jvmToolchain(17)
}
常见错误:
- 只设
android.kotlinOptions.jvmTarget = "17",但没设kotlin.jvmToolchain(17)→ 构建时compileDebugKotlin仍可能用 JDK 11 执行,导致 class version 不一致 - AGP 升级后忘记更新
kotlinOptions.jvmTarget字符串格式 → Gradle 报错Cannot set readonly property: jvmTarget - 在
build.gradle(Groovy)里混用 Kotlin DSL 写法,比如kotlin { jvmToolchain(17) }→ Groovy 文件不识别该语法,直接解析失败
验证是否生效的最快方式
别依赖 IDE 显示或文档描述,直接看编译产物和运行行为:
- 执行
./gradlew compileKotlin --info,日志中应出现Using JVM toolchain: 17和Kotlin compiler args: -jvm-target 17 - 反编译
build/classes/kotlin/main/下任意 class,用javap -v MyClass.class | grep "major version",结果应为61(对应 Java 17) - 在 JDK 11 环境下运行生成的 JAR,应立刻失败并报
Unsupported major.minor version 61—— 这说明设置已生效;反之则配置未落地
工具链不是“设了就完事”的开关,它是 Gradle 对整个 JVM 生态的契约声明。漏掉任一环节,Kotlin 字节码就可能在生产环境静默崩溃。











