Gradle 8.0+ 中 kotlinOptions 已被彻底移除,必须迁移到 compilerOptions,否则 jvmTarget 等配置失效,导致字节码版本不一致、K2 前端未启用及 Inconsistent JVM-target compatibility 错误。

Gradle 8.0+ 中 kotlinOptions 已被正式弃用,必须迁移到 compilerOptions,否则同步会报错或编译行为异常(比如 jvmTarget 不生效、-Xuse-k2 被忽略)。这不是可选项,是强制升级路径。
为什么不能继续用 kotlinOptions
Gradle 8.0 开始,Kotlin 插件(1.9.0+)彻底移除了 kotlinOptions 的 DSL 支持。它不再解析该块内的任何配置,包括 jvmTarget、freeCompilerArgs、apiVersion 等。即使你写了,Gradle 也当没看见——构建可能“成功”,但实际字节码版本、语言特性支持都按默认值走,极易引发运行时 IncompatibleClassChangeError 或 UnsupportedClassVersionError。
常见错误现象:
-
compileKotlin任务不报错,但生成的 class 文件仍是 JVM 1.8 字节码(哪怕你写了kotlinOptions.jvmTarget = "17") -
-Xuse-k2在freeCompilerArgs里加了,但 Kotlin 编译器根本没启用 K2 前端 - Android 项目同步后提示
Inconsistent JVM-target compatibility detected,根源就是kotlinOptions失效导致 Kotlin 和 Java 编译目标不一致
compilerOptions 的基本写法(Kotlin DSL)
替换位置:把原来模块级 build.gradle.kts 中的 kotlinOptions { ... } 块,整体替换成 compilerOptions { ... },并注意类型和 setter 的变化:
-
jvmTarget必须用set()方法,且参数是JvmTarget.JVM_17这类枚举,不再是字符串 -
freeCompilerArgs改为freeCompilerArgs.addAll(listOf(...)),不能直接赋值 -
apiVersion和languageVersion同样需用set(),且值为KotlinVersion.KOTLIN_1_9等枚举 -
progressiveMode、allWarningsAsErrors等布尔开关统一用set(true/false)
示例(迁移前后对比):
/* 迁移前(Gradle < 8.0,已失效) */
kotlin {
kotlinOptions {
jvmTarget = "17"
freeCompilerArgs += "-Xuse-k2"
apiVersion = "1.9"
languageVersion = "1.9"
}
}
<p>/<em> 迁移后(Gradle 8.0+,必须) </em>/
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
freeCompilerArgs.addAll(listOf("-Xuse-k2", "-opt-in=kotlin.ExperimentalStdlibApi"))
apiVersion.set(KotlinVersion.KOTLIN_1_9)
languageVersion.set(KotlinVersion.KOTLIN_1_9)
progressiveMode.set(true)
allWarningsAsErrors.set(false)
}
}容易踩的坑:jvmToolchain vs compilerOptions.jvmTarget
这两个配置不是互斥的,而是分工不同,必须同时设对:
-
jvmToolchain(17)控制 Kotlin 编译器进程本身运行在哪个 JDK 上(影响kotlinc启动、注解处理器执行环境) -
compilerOptions.jvmTarget.set(JvmTarget.JVM_17)控制最终生成的字节码版本(影响运行时兼容性) - 如果只设
jvmToolchain而漏掉compilerOptions.jvmTarget,Kotlin 仍会默认输出 JVM 1.8 字节码(尤其在旧版 Kotlin 插件下) - Android 项目中,还必须确保
android.compileOptions.sourceCompatibility和targetCompatibility与之严格一致,否则触发Inconsistent JVM-target compatibility报错
多模块项目里别漏掉子模块
根项目的 build.gradle.kts 通常只配插件和仓库,真正的 kotlin { compilerOptions { ... } } 必须写在每个需要编译 Kotlin 的子模块(如 app/、lib-core/)的 build.gradle.kts 里。常见疏忽:
- 只改了
app/build.gradle.kts,忘了feature-login/build.gradle.kts - 用了
subprojects统一配置,但没检查是否所有子项目都应用了org.jetbrains.kotlin.jvm插件(没应用的模块里写compilerOptions会直接报错) - KMM(Kotlin Multiplatform)项目中,
androidMain和jvmMain的compilerOptions可能需要不同jvmTarget,不能一刀切
最稳妥的做法:逐个打开每个含 .kt 文件的模块的 build.gradle.kts,确认 kotlin { compilerOptions { ... } } 存在且正确。

















