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

问题描述

根据“Toolchains for plugin authors”,应该可以从自定义任务中访问配置的 JavaToolchainSpec。我尝试在自定义插件中使用这种方法,该插件根据 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 将不可用(留下您报告的错误)