Kotlin标准库版本冲突在编译时爆发,因其metadata版本由编译器硬编码并强制校验:1.9.20编译器只接受metadata版本为1.9.0的类,若依赖含1.8.0 metadata(如旧版AAR),即报“Incompatible classes”错误;根本解法是统一Kotlin插件、stdlib及构建模块(如buildSrc)版本至同一语义版本(如1.9.20),而非仅调整implementation依赖。

为什么 Kotlin 标准库版本冲突总在编译时才爆?
因为 kotlin-stdlib 不是普通依赖,它是 Kotlin 编译器“自带的运行时契约”。当你用 Kotlin 1.9.20 编译代码,生成的字节码里会带一个 Kotlin.Metadata 注解,里面硬编码了 metadata 版本号(比如 1.9.0)。如果某个第三方库是用 Kotlin 1.8.20 打的包,它的 kotlin-stdlib 是 1.8.20,metadata 是 1.8.0;而你的项目用 1.9.20 编译器去读它,就会报:Incompatible classes were found in dependencies. The binary version of its metadata is 1.8.0, expected version is 1.9.0。
这不是 Gradle 解析错了,而是 Kotlin 编译器在加载类时主动拒绝——它只认自己版本能解析的 metadata 格式。所以你改 implementation 里的版本号没用,关键得让整个工具链统一用同一套 Kotlin 编译器语义。
怎么锁定 Kotlin 编译器和标准库版本?
Gradle 8.0+ 原生支持 kotlin DSL 配置块,这是最干净、最优先的方式:
kotlin {
jvmToolchain(17)
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9)
}
}
同时必须确保以下三点同步:
-
ext.kotlin_version = "1.9.20"(或通过gradle/libs.versions.toml统一声明)在根build.gradle中定义,并在dependencies块中显式声明:implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" -
plugins { id("org.jetbrains.kotlin.jvm") version "$kotlin_version" apply false }—— 插件版本必须和 stdlib 版本严格一致 - 所有模块(包括
buildSrc和build-logic)都使用同一个kotlin_version,不能有模块漏掉或写死旧版本
遇到 “metadata 版本不匹配” 报错,先别删依赖
典型错误信息:Kotlin: incompatible version of Kotlin. metadata is 1.8.0, expected version is 1.9.0。这说明你项目里混进了低版本 Kotlin 编译产出的二进制(比如某个老 AAR、某个未更新的私有 SDK、甚至是你自己模块之前用旧插件打的 snapshot)。
排查路径很明确:
- 运行
./gradlew app:dependencies --configuration debugRuntimeClasspath | grep kotlin,看哪些传递依赖拉进了kotlin-stdlib:1.8.20或类似旧版 - 对可疑依赖,用
jar -tvf xxx.aar | grep Metadata检查其 class 文件是否含Kotlin$Metadata注解,并反编译一个 class 看@Metadata注解里的version = {1, 8, 0} - 确认后,用
force强制统一(仅限临时救急):configurations.all { resolutionStrategy { force "org.jetbrains.kotlin:kotlin-stdlib:1.9.20" } }
注意:force 只能解决 stdlib 版本,无法修复由旧版编译器生成的、已损坏的 @Metadata 结构。真遇到这种库,唯一稳妥方案是联系提供方升级或自己 fork 重编译。
多模块项目最容易忽略的坑:buildSrc 和 build-logic 的 Kotlin 版本
很多团队把构建逻辑抽到 buildSrc 或 build-logic 模块,却忘了它们自己也要用 Kotlin 写——而这些模块的 build.gradle.kts 是被 Gradle 的 Kotlin DSL 引擎执行的,它底层用的是 Gradle 自带的 Kotlin 编译器副本,**和你项目里声明的 kotlin_version 完全无关**。
这意味着:buildSrc 里写的 Kotlin 代码,实际编译器版本取决于你当前 Gradle wrapper 版本内置的 Kotlin 版本(比如 Gradle 8.4 内置 Kotlin 1.9.10)。如果你项目用 1.9.20,但 buildSrc 用了 1.9.10 的 API(比如 KotlinCompile 的某个新属性),就会在构建阶段直接失败。
解决方案只有两个:
- 升级 Gradle wrapper 到匹配你项目 Kotlin 版本的最小兼容版本(查 Kotlin 兼容矩阵)
- 或者,彻底放弃
buildSrc,改用预编译脚本插件(build-logic),并在其build.gradle.kts中显式声明:plugins { kotlin("jvm") version "1.9.20" },这样它的编译器就和主项目对齐了
这个点极隐蔽——报错不会说“buildSrc 版本不对”,只会抛出 Unresolved reference 或 No signature of method,但根源往往就在这里。


















