You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Gradle后Ant闭包触发配置缓存报错,求解决方法

问题描述

我创建了一个用于复制并FTP传输安装包的Gradle任务,原脚本如下:

task ftp(dependsOn: "copyApk") {
    doLast {
        ant {
            taskdef(name: 'ftp',
                    classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                    classpath: configurations.ftpAntTask.asPath)
            ftp(server: "ftp.mydomain.com", userid: "ftp.mydomain.com|administrator", password: "adkjadfsid", remoteDir: "download") {
                fileset(dir: "E:/.../download/") {
                    include(name: "my-app.apk")
                }
            }
        }
    }
}

该脚本正常运行多年。近期我将Android Studio升级至Giraffe版本,同时升级了Gradle等一系列组件,并按照Android Studio的建议将任务脚本修改为:

tasks.register('ftp') {
    dependsOn "copyApk"
    doLast {
        ant {
            taskdef(name: 'ftp',
                    classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                    classpath: configurations.ftpAntTask.asPath)
            ftp(server: "ftp.mydomain.com", userid: "ftp.mydomain.com|administrator", password: "adkjadfsid", remoteDir: "download") {
                fileset(dir: "E:/.../download/") {
                    include(name: "my-app.apk")
                }
            }
        }
    }
}

运行该任务时出现以下错误:

Cannot reference a Gradle script object from a Groovy closure as these are not supported with the configuration cache.

问题出在ant {这一行,需要解决思路。

解决思路

错误根源是Gradle配置缓存机制不允许在Groovy闭包中直接引用Gradle脚本对象(比如configurations),而ant {}闭包会隐式持有脚本上下文,导致序列化失败。以下是几种可行的修复方案:

方案1:提前获取配置路径,避免闭包内引用Gradle对象

在任务的配置阶段提前把configurations.ftpAntTask.asPath的值存为变量,再在doLast闭包中使用,切断闭包与Gradle配置对象的直接关联:

tasks.register('ftp') {
    dependsOn "copyApk"
    // 配置阶段提前获取classpath路径
    def ftpAntClasspath = configurations.ftpAntTask.asPath
    doLast {
        ant.taskdef(name: 'ftp',
                classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                classpath: ftpAntClasspath)
        ant.ftp(server: "ftp.mydomain.com", userid: "ftp.mydomain.com|administrator", password: "adkjadfsid", remoteDir: "download") {
            fileset(dir: "E:/.../download/") {
                include(name: "my-app.apk")
            }
        }
    }
}

方案2:显式创建AntBuilder实例,避免隐式脚本上下文

改用显式实例化AntBuilder的方式,替代Groovy DSL的ant {}闭包,彻底切断闭包与Gradle脚本对象的隐式关联:

tasks.register('ftp') {
    dependsOn "copyApk"
    doLast {
        def antBuilder = new AntBuilder()
        antBuilder.taskdef(name: 'ftp',
                classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                classpath: configurations.ftpAntTask.asPath)
        antBuilder.ftp(server: "ftp.mydomain.com", userid: "ftp.mydomain.com|administrator", password: "adkjadfsid", remoteDir: "download") {
            fileset(dir: "E:/.../download/") {
                include(name: "my-app.apk")
            }
        }
    }
}

方案3:临时禁用该任务的配置缓存(不推荐)

如果暂时不想适配配置缓存,可以给单个任务禁用配置缓存,但这会失去配置缓存带来的性能优化:

tasks.register('ftp') {
    dependsOn "copyApk"
    // 禁用该任务的配置缓存
    notCompatibleWithConfigurationCache("使用Ant闭包无法兼容配置缓存")
    doLast {
        ant {
            taskdef(name: 'ftp',
                    classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                    classpath: configurations.ftpAntTask.asPath)
            ftp(server: "ftp.mydomain.com", userid: "ftp.mydomain.com|administrator", password: "adkjadfsid", remoteDir: "download") {
                fileset(dir: "E:/.../download/") {
                    include(name: "my-app.apk")
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Hong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:25:36