Gradle 在 jar 之后不运行复制任务

问题描述

我正在尝试做这样的事情:

jar {
  doLast{
    from "build/libs/TheJar.jar"
    into "."
   }
}

到目前为止,我已经尝试了各种教程,包括answer 中的所有形式,但都没有奏效。唯一有效的是调用一个单独的任务,但我想知道为什么我的构造是错误的,为什么我不能在 jar 或 shadowJar 任务之后运行某些东西。

解决方法

看起来您在链接帖子中获取了部分答案,并以某种方式将它们混合在一起,但不知道您的最终代码实际做了什么。

Gradle 中的任务可能有一个类型(例如 CopyJar、...)。此类型定义任务执行后将执行的操作(所谓的任务操作)。没有类型的任务在执行时不会做任何事情,除非您手动添加任务操作。使用 doFirst 会将传递的操作(也称为闭包)添加到任务操作列表的开头,使用 doLast 会将其添加到列表的末尾。

doFirstdoLast 闭包之外的所有内容都不是任务执行的一部分,但可用于配置任务:

task example {
    doLast {
        println "second action"
    }
    doFirst {
        println "first action"
    }
    println "configuration"
}

使用 gradle example 运行上面的代码,您将看到日志消息的顺序为 configurationfirst actionsecond action

任务配置将运行,即使该任务稍后不会执行。即使您调用 gradle(没有任何任务名称作为参数),控制台仍会打印 configuration。这是链接问题中的实际问题。

让我们来看看真正的问题:如何复制文件?

好吧,Gradle 提供了两种复制文件的方法。第一个是任务类型 Copy。您可以基于此类型创建任务,应用您的配置,然后直接从命令行调用它或使用 dependsOnfinalizedBy 定义任务依赖项:

task copySomeFiles(type: Copy) {
    from '...'
    into '...'
}

但是,您不想创建额外的任务。 Gradle 也有一个名为 copy 的方法,可以在脚本中的任何位置调用它并立即复制文件:

copy {
    from '...'
    into '...'
}

上面的代码将复制您的文件,但它会在每次 Gradle 执行时复制您的文件(这可能经常发生,例如在使用 IDE 时)。要解决此问题,您可以将带有 copy 的代码移动到任务操作,例如在 doFirstdoLast 闭包内:

jar {
    doLast {
        copy {
            from "build/libs/TheJar.jar"
            into "."
        }
    }
}

如您所见,您的代码缺少 copy 语句。现在,每当您的任务 jar 被执行时,它的最后一个任务操作将按预期复制文件。

额外问题:为什么没有错误?

您的情况的“问题”是您的代码是完全有效的 Gradle 代码。任务 jar 的类型为 JarJar 类型的每个任务都可以使用名为 frominto 的方法进行配置。方法 from 将文件添加到 JAR 文件,方法 into 设置 JAR 内的目标目录。因此,您的代码不是复制,而是配置基础任务 jar。但是,这没有负面影响,因为此配置应用在 doLast 中,它仅在 JAR 文件创建后才运行。已经发生的事情无法配置。