2017-01-20 129 views
2

約搖籃(3.3版)如何解決在多項目設置任務相關性(用java子項目)一個小問題。我是很新的,所以也許搖籃這是一個愚蠢的問題...搖籃dependson與defaultTasks在多項目

我想實現一個任務被編譯前一個編譯後的執行和。

使用它按預期工作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'. 

任何想法,爲什麼是這樣的話?

回答

1

有了您的build.gradle,因爲它是,剛剛運行「gradle這個」給我的3.3安裝了同樣的錯誤。

有你在這裏面臨2個問題。

1.多項目子項目VS allprojects

的第一個問題是,defaultTasks在主的build.gradle定義,但你的Java插件只包含在子項目。

在一個多項目構建中,'master'項目不是子項目部分的一部分(只有所有項目都會影響主項目),但是'defaultTasks'是在頂層定義的,所以運行'gradle'將會調用主項目中的defaultTasks,並在類任務上失敗,因爲它不加載java插件。

爲了解決這個問題,移動「應用插件」線allprojects(但僅限於該圖中,正常情況下你不希望在主加載Java插件,因爲它通常是關於建立分項目)。

2. defaultTasks VS dependsOn

第二個問題(假設您移動應用插件),那麼你會打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這個按字母順序運行它們(因爲它們之間存在,在這種情況下沒有依賴它會按字母順序運行)。與mustRunAfter

在這種情況下

$ 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 

修復相關性順序,您可以通過添加修復它下面到doIt方法:

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

這將迫使在B任務稍後完成。

+0

感謝您的詳細解答,馬克!特別是.mustRunAfter是非常有幫助的。 – Axel

+0

@Axel - 很高興我能幫上忙。我確實發現了你的問題,因爲我有類似的問題,並且在解決我的問題時,它也解決了你的問題。 –

+0

這就是這些雙贏局面之一:-) – Axel