Kotlin 编译在 BTA 里空指针:核对 BOM 导入组合
Gradle 9.6.1、KGP 2.4.10 与依赖管理插件导入 BOM 的组合,会在编译参数构造时空指针。旧编译入口只能作为有版本边界的临时绕行。
:compileKotlin 还没开始编译业务源码,就报 getPluginClasspaths() 返回 null,并在 BuildToolsApiCompilationWork 中失败。若项目使用 KGP 2.4.10,且 io.spring.dependency-management 正在导入 BOM,应先对照这条特定组合,不要为不存在的源码错误改业务代码。
明确的环境组合是 Gradle 9.6.1、KGP 2.4.10、依赖管理插件 1.1.7、Spring Boot 4.1.0 BOM 和 JDK 25。即使项目没有配置 Kotlin 编译器插件,也可以在构造编译参数时碰到空数组引用。现有证据不能把 JDK 25 单独确定为根因。
保留依赖语义,先比较编译入口
在这一版 KGP 中,可对原失败任务做一次受控的旧入口比较:
./gradlew -Pkotlin.compiler.runViaBuildToolsApi=false :domain:compileKotlin --rerun-tasks --console=plain
任务路径是示例,应换成原失败模块并保留原来的构建条件。命令会真实执行构建与项目脚本,不是只读检查。具体组合中,保留 BOM、只改为旧编译入口可以通过;这能提供一条临时绕行,但不能证明所有使用 BTA 的项目都有同样缺陷。
删除 BOM 导入也可能改变结果,却会改变依赖管理。不要为了让编译阶段越过空指针,把项目的版本约束一并取消。需要改变依赖管理方案时,应另行检查解析到的完整版本组合。
这项开关已经弃用
KGP 2.4.10 的正式实现仍读取 kotlin.compiler.runViaBuildToolsApi,默认值为 true,同时把旧入口标为弃用。临时设置应限定到受影响构建,不应写进无期限的全局 Gradle 配置,也不能承诺后续 KGP 一直保留它。
查看实际应用的 Kotlin Gradle 插件版本,而不只是 gradle --version 输出的内嵌 Kotlin。编译任务使用的 KGP、构建脚本语言及 Gradle 本身是不同层次;只升级或降级其中一个,不一定改变这条路径。
验收先确认原任务越过参数构造并完成编译,再检查依赖解析、测试和产物。后续评估兼容的 KGP 版本时,去掉临时开关,用原 BOM 与 BTA 入口重新回归;旧入口成功并不代表新入口已经修复。


