【问题标题】:Gradle, dependsOn orderingGradle,取决于排序
【发布时间】:2020-06-25 23:41:07
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: gradle


    【解决方案1】:

    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()...

    【讨论】:

      【解决方案2】:

      您使用的是 Gradle 1.5,而 mustRunAfter 的日期来自 1.6。当前版本是 1.8。

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

      【讨论】:

        【解决方案3】:

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

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

        您可以在Gradle User GuideGradle forums 中阅读配置阶段与执行阶段。

        【讨论】:

          【解决方案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
          }
          

          【讨论】:

          • 我担心这会导致每个 :allTestReleaseUnitTest 将首先启动 :allClean,即使是直接启动,而不是作为 buildAppRelease 任务的一部分...
          • 我不敢相信 Gradle 不尊重依赖的顺序。这太烦人了。
          【解决方案5】:

          我发现如果我同时使用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)
          }
          

          【讨论】:

            【解决方案6】:

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

            ktlint.mustRunAfter ktlintFormat
            compileKotlin.dependsOn ktlintFormat,ktlint
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-04-25
              • 1970-01-01
              相关资源
              最近更新 更多