如何从自定义 Gradle 任务中访问 `JavaToolchainSpec`

How to access `JavaToolchainSpec` from within custom Gradle task

根据“Toolchains for plugin authors" it should be possible to access the configured JavaToolchainSpec from within a custom task. I try to use this approach within a custom plugin which creates a task based on the presence of the JavaPlugin并查询配置的languageVersion属性。这里是一个最小的例子。

build.gradle

plugins {
  id 'application'
  id 'com.example.myplugin'
}

...

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

MyPlugin.kt

class MyPlugin : Plugin<Project> {

  override fun apply(target: Project) {
    target.plugins.withType<JavaPlugin> {
      target.tasks.create<MyTask>("mytask")
    }
  }
}

MyTask.kt

abstract class MyTask : DefaultTask() {
  
  init {
    val extension = project.extensions.getByType<JavaPluginExtension>();
    val languageVersion = extension.toolchain.languageVersion.get();

    ...
  }
}

一旦 Gradle 创建 MyTask 并查询 languageVersion 属性,构建将失败并出现以下错误。

Cannot query the value of property 'languageVersion' because it has no value available.

我的猜测是我太早访问了扩展,此时它还没有设置它的值。我现在的问题是是否有一种方法可以将配置的属性(最好使用惰性机制)与任务连接起来。

显然您必须在 java 插件扩展中配置工具链对象才能使用 JavaToolchainService,使用类似:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(11)
   }
}

如果您不这样做,Gradle 将默认为当前 JVM,并且整个工具链 API 将不可用(留下您报告的错误)