16

在 Gradle 中订购时感到困惑。我是一个新手,以前使用 Ant 进行构建,玩过 Gradle,这可以解释其中的一些原因

简要背景(以防有人问“你为什么要这样做”)。我们在 war 文件中发布了一个 Java WebStart 应用程序。Java 7(-40 及更高版本)提示用户有关缺少元素的格式不正确的 jar 文件。我想自动化一个引发战争的过程;从“bin”文件夹中提取 JavaWS 的 jar;将元素添加到 Manifest 稍后我将重新签署 jar 并重新组装战争,但现在我只想添加 Manifest 条目。

我的问题是我定义了具有dependsOn 元素的任务,但任务似乎以错误的顺序运行(请参阅下面的gradle 文件)。我期望的是按顺序运行的任务:删除目录;发动战争;解除战争;将元素添加到 jar 中。我看到的(从日志文件)是:元素被添加到 jar 中,这实际上创建了一个新的 jar,删除了 dir 并且战争是 unwar'ed 所以我最终得到了原始的战争文件内容。

我检查了:Gradle Task To Call Other Tasks In Order但是,我似乎根本无法使用 mustRunAfter ,可能与我拥有的 gradle 版本有关,但无论如何我真的不想控制不同任务的顺序,我希望(在我基于 Ant 的思想中)我可以通过让任务相互依赖来定义我想要的顺序。

任何人都可以看到我的构建文件中的缺陷吗?注意:如果我从 resignclientjars 任务中删除“dependsOn”并在运行其他任务后手动运行它,它一切正常,我得到我的 jar 与清单中的新元素,所以我有一个可行的解决方法,但更喜欢知道我在这里做错了什么。

task (deletework, type: Delete) {
    delete 'workYYY'
}

task (getlaganwar, type: Copy, dependsOn: deletework) {
    from "d:/dev/v8-0-5/wars"
    into "workYYY"
    include 'lagan.war'
}

task (unwar, type: Copy, dependsOn: getlaganwar) {
    from zipTree(file('workYYY/lagan.war'))
    into file("workYYY/lagan")
}

task (resignclientjars, type: Copy, dependsOn: unwar) {
//task (resignclientjars, type: Copy) {

//  mustRunAfter unwar

    def workDir = file("workYYY/lagan")
    def binDir = file(new File(workDir, "bin"))

    def collection = files { binDir.listFiles() }
    collection.each { 
        File jarFile = new File(binDir, it.name)
        ant.echo(message: "updating:${jarFile.absolutePath}")
        ant.jar(jarfile: jarFile, update: 'true') {
            manifest {
                attribute(name: 'Implementation-Title', value: 'Lagan Enterprise')
                attribute(name: 'Implementation-Vendor', value: 'Lagan Enterprise')
                attribute(name: 'Implementation-Version', value: 'Lagan Enterprise')
                attribute(name: 'Application-Name', value: 'Lagan Enterprise')
                attribute(name: 'Permissions', value: 'all-permissions')
            }
        }
    }
}

//unwar.mustRunAfter getlaganwar
//getlaganwar.mustRunAfter deletework
//resignclientjars.mustRunAfter getlaganwar

调试输出包含以下内容:

[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      :resignclientjars
[sts] -----------------------------------------------------

12:06:19.658 [WARN] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:echo] updating:D:\dev\util\java7-clientjars\workYYY\lagan\bin\DebugWinIEBrowser.jar
12:06:19.666 [WARN] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:echo] updating:D:\dev\util\java7-clientjars\workYYY\lagan\bin\DebugWinMSWord.jar
12:06:19.670 [WARN] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:echo] updating:D:\dev\util\java7-clientjars\workYYY\lagan\bin\WinIEBrowser.jar
12:06:19.674 [WARN] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:echo] updating:D:\dev\util\java7-clientjars\workYYY\lagan\bin\WinMSWord.jar

12:06:19.690 [INFO] [org.gradle.execution.TaskNameResolvingBuildConfigurationAction] Selected primary task ':resignclientjars'
12:06:19.692 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire exclusive lock on task artifact state cache (D:\dev\util\java7-clientjars\.gradle\1.5\taskArtifacts).
12:06:19.692 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired.
12:06:19.692 [INFO] [org.gradle.BuildLogger] Tasks to be executed: [task ':deletework', task ':getlaganwar', task ':unwar', task ':resignclientjars']

12:06:19.693 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':deletework'
12:06:19.693 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Determining if task ':deletework' is up-to-date
12:06:19.694 [INFO] [org.gradle.api.internal.changedetection.ShortCircuitTaskArtifactStateRepository] Task ':deletework' has not declared any outputs, assuming that it is out-of-date.
12:06:19.694 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] task ':deletework' is not up-to-date

12:06:19.695 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':deletework'.
12:06:19.695 [DEBUG] [org.gradle.api.internal.file.copy.DeleteActionImpl] Deleting D:\dev\util\java7-clientjars\workYYY

12:06:19.934 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':deletework'
12:06:19.934 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :getlaganwar
12:06:19.934 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':getlaganwar'
12:06:19.936 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Determining if task ':getlaganwar' is up-to-date

12:06:19.942 [INFO] [org.gradle.api.internal.changedetection.DefaultTaskArtifactStateRepository] Executing task ':getlaganwar' due to:
Output file D:\dev\util\java7-clientjars\workYYY for task ':getlaganwar' has changed.
Output file D:\dev\util\java7-clientjars\workYYY\lagan.war has been removed for task ':getlaganwar'.
12:06:19.942 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] task ':getlaganwar' is not up-to-date

12:06:19.944 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':getlaganwar'.

12:06:20.564 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':getlaganwar'
12:06:20.565 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :unwar
12:06:20.565 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':unwar'
12:06:20.586 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Determining if task ':unwar' is up-to-date
12:06:20.588 [DEBUG] [org.gradle.api.internal.changedetection.DefaultFileCacheListener] Can cache files for ZIP 'D:\dev\util\java7-clientjars\workYYY\lagan.war'
12:06:20.588 [DEBUG] [org.gradle.api.internal.changedetection.DefaultFileCacheListener] Can cache files for file 'D:\dev\util\java7-clientjars\workYYY\lagan'
12:06:24.096 [INFO] [org.gradle.api.internal.changedetection.DefaultTaskArtifactStateRepository] Executing task ':unwar' due to:
Output file D:\dev\util\java7-clientjars\workYYY\lagan for task ':unwar' has changed.

12:06:24.097 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] task ':unwar' is not up-to-date

12:06:24.100 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':unwar'.

12:06:27.863 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':unwar'
12:06:27.863 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :resignclientjars
12:06:27.864 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':resignclientjars'
12:06:27.864 [INFO] [org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter] Skipping task ':resignclientjars' as it has no source files.
12:06:27.864 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':resignclientjars'
12:06:27.864 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :resignclientjars UP-TO-DATE
12:06:27.865 [DEBUG] [org.gradle.execution.taskgraph.DefaultTaskGraphExecuter] Timing: Executing the DAG took 8.173 secs
12:06:27.865 [LIFECYCLE] [org.gradle.BuildResultLogger] 
12:06:27.865 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD SUCCESSFUL
12:06:27.865 [LIFECYCLE] [org.gradle.BuildResultLogger] 
12:06:27.866 [LIFECYCLE] [org.gradle.BuildResultLogger] Total time: 8.886 secs
4

6 回答 6

11

Gradle 中不可预测的依赖顺序真的很烦人。

以下是按顺序执行相关任务的解决方法:

task dist(type: Zip) {
    def tasks = [clean, jar, test, docs]
    for (int i = 0; i < tasks.size() - 1; i++) {
        tasks[i + 1].mustRunAfter(tasks[i])
    }
    dependsOn(tasks)

    //...other stuff
}

可能这种解决方法可以以可重用的方式提取为strictDependsOn()......

于 2018-04-04T21:30:40.950 回答
8

您使用的是 Gradle 1.5,并且mustRunAfter从 1.6 开始。当前版本是 1.8。

dependsOn不修复任务的任何顺序。这已经在各种错误报告中被讨论得令人作呕。解决方法是使用各个任务之间的依赖关系,或mustRunAfter.

于 2013-10-30T12:22:10.383 回答
6

您的构建脚本的问题不是任务依赖关系,而是任务定义resignclientjars不正确。它在配置阶段(即对于每个构建调用)而不是在执行阶段完成其工作。正确的任务定义如下所示:

task resignclientjars(dependsOn: unwar) {
    doLast {
       ...
    }
} 

您可以阅读Gradle 用户指南Gradle 论坛中的配置阶段与执行阶段。

于 2013-10-30T14:22:26.670 回答
4

无论出于何种原因,gradle 确实保证了dependsOn 的顺序,之后他们添加了mustRunAfter,但是您必须像白痴一样将自己链接起来,所以这里有一个实用程序:

task buildAppRelease() {
    group = "build"
    dependsOn ordered(":allClean", ":allTestReleaseUnitTest", ":app:assembleRelease")
}

def ordered(String... dependencyPaths) {
    def dependencies = dependencyPaths.collect { tasks.getByPath(it) }
    for (int i = 0; i < dependencies.size() - 1; i++) {
        dependencies[i + 1].mustRunAfter(dependencies[i])
    }
    return dependencies
}
于 2019-08-03T02:02:18.327 回答
2

我发现如果我同时使用dependsOn和mustRunAfter,它就可以工作。这是运行两个任务的示例,一个(自定义注册的“importUnicodeFiles”任务)在“this”项目中,另一个(预定义的“run”任务)在名为“:unicode”的同级项目中:

tasks.register("rebuildUnicodeFiles") {
    description = "Force the rebuild of the `./src/main/resources/text` data"
    val make = project(":unicode").tasks["run"]
    val copy = tasks["importUnicodeFiles"]
    dependsOn(make)
    dependsOn(copy)
    copy.mustRunAfter(make)
}
于 2020-06-25T13:53:19.863 回答
1

我已经能够使用如下所示的 dependsOn 和 mustRunAfter 来定义任务的顺序。注意,这里我想先运行 ktlintFormat 然后运行 ​​ktlint。

ktlint.mustRunAfter ktlintFormat
compileKotlin.dependsOn ktlintFormat,ktlint
于 2019-12-10T01:45:53.053 回答