【问题标题】:Gradle dependson vs. defaultTasks in multi-project多项目中的 Gradle 依赖与 defaultTasks
【发布时间】:2017-02-10 22:23:27
【问题描述】:

关于 Gradle(3.3 版)如何解决多项目设置(带有 java 子项目)中的任务依赖关系的一个小问题。我对 gradle 很陌生,所以也许这是一个愚蠢的问题......

我想实现一个在编译前执行的任务,一个在编译后执行的任务。

使用 defaultTasks 它可以按预期工作。但是当使用 dependsOn 定义任务时,它不会。

我的根build.gradle 文件如下所示:

defaultTasks 'a', 'classes', 'b'

task a {
    doLast {
        println 'before compile'
    }
}

task b {
    doLast {
        println 'after compile'
    }
}

task doIt(dependsOn: [a, 'classes', b]) {
    doLast {
        println('done!')
    }
}

allprojects {
    group = 'foo'

    repositories {
        mavenCentral()
        maven {
            url 'https://maven.atlassian.com/3rdparty/'
        }
    }
}

subprojects {
    ext {
        springVersion = '4.3.5.RELEASE'
    }
    apply plugin: 'java'
    dependencies {
        compile fileTree(dir: 'lib', include: '*.jar')
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
}

当我执行gradle 时,默认任务按预期执行:我得到“编译前”,然后编译所有子项目,然后是“编译后”。

当我执行gradle doIt 时,我收到以下错误消息

Task with path 'classes' not found in root project 'teambits-core'.

知道为什么会这样吗?

【问题讨论】:

    标签: gradle


    【解决方案1】:

    使用您的 build.gradle,只需运行 'gradle' 在我的 3.3 安装中也会出现同样的错误。

    您在这里面临 2 个问题。

    1.多项目子项目与所有项目

    第一个问题是 defaultTasks 是在主 build.gradle 中定义的,但您的 java 插件只包含在子项目中。

    在多项目构建中,“主”项目不是子项目部分的一部分(只有所有项目会影响主项目),但您的“defaultTasks”是在顶层定义的,因此运行“gradle”将调用主项目中的 defaultTasks 并在 classes 任务上失败,因为它不加载 java 插件。

    要解决此问题,请将“应用插件”行移至所有项目(但仅用于此说明,通常您不希望将 java 插件加载到主项目中,因为它通常与设置子项目有关)。

    2。 defaultTasks 与 dependsOn

    第二个问题是(假设您移动了 apply 插件)那么您将发现 defaultTasks 和 dependsOn 之间的真正区别。

    defaultTasks 按照您指定的顺序运行任务:

    $ gradle
    :a
    before compile
    :compileJava UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :b
    after compile
    
    BUILD SUCCESSFUL
    
    Total time: 0.765 secs
    

    但是以列表顺序运行 doIt 将导致 gradle 按字母顺序运行它们(因为它们之间没有依赖关系,在这种情况下它将按字母顺序运行它们)。

    $ gradle doit
    :a
    before compile
    :b
    after compile
    :compileJava UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :doIt
    done!
    
    BUILD SUCCESSFUL
    
    Total time: 0.733 secs
    

    使用 mustRunAfter 修复依赖顺序

    在这种情况下,您可以通过在 doIt 中添加以下内容来修复它:

    task doIt(dependsOn: [a, 'classes', b]) {
        b.mustRunAfter(':classes')
        doLast {
            println('done!')
        }
    }
    

    这将迫使 b 任务稍后完成。

    【讨论】:

    • 感谢您的详细回答,马克!尤其是 .mustRunAfter 非常有帮助。
    • @Axel - 很高兴我能帮上忙。我实际上找到了您的问题,因为我遇到了类似的问题,并且在解决我的问题时,它也解决了您的问题。
    • 这是双赢的局面之一 :-)
    猜你喜欢
    • 1970-01-01
    • 2018-11-10
    • 2015-08-22
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    相关资源
    最近更新 更多