自建 JavaCompile 没用项目 JDK:为任务显式设置 javaCompiler
Gradle 项目已设置 Java toolchain,自建 JavaCompile 却仍由 daemon 的 JDK 编译。针对独立任务补上编译器 provider,并核对真正执行的 JDK。
java.toolchain 已要求某个 JDK,普通 compileJava 也使用它,自建的 JavaCompile 任务却仍调用 Gradle daemon 所在的 JDK。遇到编译结果或 API 支持不一致时,应单独核对自建任务的 javaCompiler,不能只看项目的 toolchain 声明。
Gradle 9.7.0、9.7.1 的这类自建任务存在明确差异:源集创建的编译任务有项目工具链约定,直接注册的 JavaCompile 可能落到当前 JVM 的默认工具链。这里不要求 daemon 与编译 JDK 相同,也不必为了一个任务全局切换 Java。
在自建任务上接入 compiler provider
项目已经应用 Java 插件并配置 java.toolchain.languageVersion 时,可在 Groovy build.gradle 中为原任务增加:
tasks.named('handCreatedCompile', JavaCompile) {
javaCompiler = javaToolchains.compilerFor {
languageVersion = java.toolchain.languageVersion
}
}
handCreatedCompile 是示例任务名,替换为已有任务。保留它原来的源码、classpath、输出目录及编译选项,不要再注册一个同名任务。compilerFor 产生工具 provider,让 Gradle 按目标语言版本选择编译器;它不是一个手写 javac 路径。
如果自建任务本来就应使用另一个 JDK,应给它独立且明确的 JavaLanguageVersion,不要跟随项目设置。项目同时使用 vendor、实现类型等工具链条件时,也要把所需条件一起纳入,避免只复制语言版本后选到另一发行版。
查看该任务,别只看 daemon
从实际执行任务的终端或 CI 查看 Gradle 版本及 daemon JVM,再检查自建任务选中的编译器路径与元数据。项目允许自动下载工具链时,第一次解析可能触发下载;离线环境应先配置可用安装,不能把找不到工具链误判为绑定没有生效。
sourceCompatibility 和 targetCompatibility 不等于选择编译器,options.release 也主要控制编译目标。修改这些值可能让旧 JDK 报不支持目标版本,却不会给它安装新能力。
改动后重新执行原自建编译任务,确认实际编译器符合要求,再验证产物目标及项目测试。普通 compileJava 成功不能替代这个任务的验收。保留局部配置差异,后续采用目标正式版本时,应复核自建任务默认选择的编译器,再决定是否撤回显式绑定。


