如何在Gradle Kotlin DSL的任务doLast块中正确使用文件级变量
问题描述
在build.gradle.kts脚本顶层定义私有变量后,尝试在任务的doLast块中使用该变量时触发配置缓存序列化错误,原代码如下:
// 移除`private`关键字可解决问题,但我们希望保留private private val someValue = "some value" tasks.register("someTask") { // 以下代码也能解决问题,但并非常规方式 // val someValue = someValue doLast { println(someValue) } }
运行时错误信息:
Task
:someTaskof typeorg.gradle.api.DefaultTask: cannot serialize Gradle script object references as these are not supported with the configuration cache
正确实现方式
方法一:配置阶段捕获变量值到局部变量
在任务配置阶段将私有变量的值复制到局部变量中,避免doLast块持有不可序列化的脚本对象引用(局部变量为基本类型,支持序列化):
private val someValue = "some value" tasks.register("someTask") { // 配置阶段捕获私有变量的值,赋值给局部变量 val localValue = someValue doLast { println(localValue) } }
方法二:使用任务的extra属性存储值
通过任务自带的extra属性存储变量值,extra属性是Gradle官方支持的可序列化容器,适配配置缓存要求:
private val someValue = "some value" tasks.register("someTask") { // 将私有变量值存入任务的extra属性 extra["taskLocalValue"] = someValue doLast { println(extra["taskLocalValue"]) } }
原理说明
报错的核心原因是:顶层私有变量属于Gradle脚本对象的成员,而脚本对象本身不可被序列化。配置缓存要求任务的所有依赖对象必须支持序列化,因此doLast块直接引用顶层私有变量时,会因持有不可序列化的脚本对象引用而触发错误。上述两种方法均规避了脚本对象引用,转而使用可序列化的独立值或官方支持的属性容器。
内容的提问来源于stack exchange,提问作者Natasha
相关产品推荐
相关产品推荐

