## 1.使用
在build.gradle中添加以下語句,表示插入java插件
~~~
apply plugin:'java'
~~~
## 2.source sets
java插件引入了sourceset這個概念,sourceset將編譯時和執行時所要用到的source文件組合在一起,其中包含java的源文件和資源文件,有的插件還包括了groovy和Scala資源文件,sourceset與編譯環境和運行環境都存在聯系。
使用sourceset的目的是將一些源文件組合起來,為了某個特殊的目的在邏輯上進行分組。例如,你可能把測試的集合單獨拿出來組合成一個sourceset,或者一些API啊,你項目中的實現類啊等等,都可以定義為一個sourceset。這只是個概念的問題,你知道知道你分組的意義:方便你管理文件。
java中定義了2個sourceset:一個是main group,還有一個是test group。
main:項目中的源文件,編譯后組裝到jar包中的。
test:項目的測試源碼,例如JUint和TestNG寫的測試代碼。
## 3.任務
#### java plugin任務
**compileJava**:目的是編譯java源文件,利用javac。依賴compile任務,屬于JavaCompile類型。
~~~
apply plugin: 'java'
compileJava {
//enable compilation in a separate daemon process
options.fork = true
//enable incremental compilation
options.incremental = true
}
~~~
**processResource**:將項目的資源文件復制到項目class目錄中。無依賴。屬于Copy類型,嚴格來說是Copy的子類。

**classes**?:組裝class目錄。依賴compileJava和processResource兩個任務,還有一些編譯的任務 。屬于Task類型。
**compileTestJava**:編譯測試源碼,利用javac。依賴compile和一些產生測試編譯環境的任務。屬于JavaCompile類型。
**processTestResource**:將測試資源文件復制到項目class文件目錄中。無依賴。屬于Copy類型。
**testClasses**:組合測試的class目錄。依賴compileTestJava和processTestResource和一些添加測試的編譯任務。屬于Task類型。
**jar**:組合成jar文件,依賴compile。屬于Jar類型。
**javadoc**:生成java幫助文檔,依賴compile。屬于Javadoc類型。
**test**:執行測試case,依賴compile,compileTest等。屬于Test類型
**uploadArchives**:上傳存檔文件。依賴那些在archives配置中產生鏡像的任務,比如jar。屬于UpLoad類型。
**clean**:刪除build文件,使項目回歸最原始狀態.屬于Delete類型。
**cleanTaskName**:刪除由任務產生的文件,比如cleanJar就是刪除有任務jar產生的文件,cleanTest就是刪除由test產生的文件。屬于Delete類型。
#### 專門處理sourceset的任務
**`compile<span class="replaceable">`SourceSet`</span>Java`**:利用javac編譯sourceset定義的源文件,依賴所有產生sourceset編譯類路徑的任務。屬于JavaCompile類型
**`process<span class="replaceable">`SourceSet`</span>Resources`**:將sourceset定義的資源文件復制到class目錄中,無依賴,屬于Copy類型。
**`<span class="replaceable">`sourceSet`</span>Classes`**:組合sourceset中定義的文件目錄,依賴compileSourceSetJava和processSourceSetResources兩個任務,屬于Task類型。
#### 生命周期類任務
**assemble:**組合分析所有的檔案文件。依賴所有的存檔文件。屬于Task類型。
**check:**執行所有的驗證類任務,依賴所有驗證類任務,包括test。屬于Task類型。
**build:**執行構建,依賴check和assemble,屬于Task類型。
**buildNeeded:**執行構建,依賴testCompile配置的子項目中build和buildNeeded任務,屬于Task類型。
**buildDependents**:執行構建,依賴當前項目的子項目的build和buildDependents任務。屬于Task類型。
**buildConfigName:**為特殊的配置類任務構建一個鏡像,該任務都是隱式添加的。依賴configName代表的任務。屬于Task類型。
**uploadConfigName**:為某一個配置任務分配鏡像,然后上傳鏡像,該任務都是隱式添加的。依賴configName定義的任務,屬于UpLoad類型。
#### 任務依賴關系圖

## 4.項目布局
java plugin規定一些項目目錄的結構,但是下面的目錄并不是要求必須存在。java在編譯的時候,會訪問下面所有的目錄,如果不存在,會記住這些沒有的目錄。
**src/main/java**:java源文件
**src/main/resources**:項目資源文件
**src/test/java**:測試源文件
**src/test/resources**:測試資源文件
**src/sourceSet/java**:sourceset定義的java源文件,注意其中的sourceSet一級是根據sourceSet定義的目錄名替換的。下同
**src/sourceSet/resourcs**:sourceset定義的資源文件
#### 修改上面默認的目錄
通過下面的方式可以修改默認的目錄結構,定義你自己想要的目錄
~~~
sourceSets{
main{
java{
srcDir 'src/java'
}
resources{
srcDir 'src/resources'
}
}
}
~~~
這是sourceSets很重要的應用。
## 5.依賴管理

上面的圖是從文檔上截取下來的,它列舉了任務之間的依賴關系,比如第一個compile是被compileJava所依賴的,即執行compile前,會先執行compile。所以要理解Name列是被依賴的任務,一般是全局任務,不是java插件特有的,而Used by tasks一般是plugin特有的。Extends則說明繼承的任務,說明該任務是在被繼承任務的基礎上擴展的。
再來看另外一張圖:

上面的圖更加的清晰展現出java任務和gradle任務之間的聯系,淺藍色的代表java任務,綠色代表gradle任務。用used by標注的代表箭頭指向的任務使用了左邊的任務。
而uploadArchives和archives之前的關系是uploads,說明uploadArchives依賴于archives任務,等archives任務生成存檔文件后,uploadArchives就會把這些存檔文件上傳。
而jar 和archives、runtime之間的關系是,在后者執行的時候,jar任務會將定義的jar包添加其中。那么這個依賴關系到底怎么算,是說jar任務依賴runtime,還是runtime依賴jar呢,應該是jar依賴runtime。因為runtime其實不管你有沒有jar任務,如果有才會將jar任務定義的東西執行,如果沒有,也是不會影響它。但是jar任務就不同了,沒有runtime,jar還有用么?
下面再來看看誰能sourceSet任務的依賴配置,于java plugin正常任務的圖是一樣的,就不多解釋了。

## 6.常用屬性
#### 目錄屬性

目錄屬性都是成雙成對出現,目錄名+目錄。目錄名是一個文件夾的名稱,相對于build目錄,而目錄則是加上build目錄。一些默認值上面都列舉出來,不想浪費時間一一列舉了。
#### 其他屬性

比較重要的是sourceSets,包含了項目中定義的sourcesets,下面一節會詳細介紹。archivesBaseName項目壓縮包的名稱。manifest操作MANIFEST文件的。
## 7.操作source set
(終于到了能寫點代碼的時候了)
#### 獲取sourceset屬性
~~~
apply plugin:'java'
println sourceSets.main.output.classesDir
println sourceSets['main'].output.classesDir
sourceSets{
println main.output.classesDir
}
sourceSets{
main{
println output.classesDir
}
}
sourceSets.all{
println name
}
~~~
執行gradle命令后輸出:
~~~
D:\GRADLE~2\0112>gradle -q
D:\gradle_product\0112\build\classes\main
D:\gradle_product\0112\build\classes\main
D:\gradle_product\0112\build\classes\main
D:\gradle_product\0112\build\classes\main
main
test
Welcome to Gradle 2.2.1.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
~~~
說明想要獲得sourcesets中屬性值的方法有很多種,上面的程序中就列舉了4種。
#### 配置sourceset屬性
~~~
apply plugin:'java'
sourceSets{
main{
java{
srcDir 'src/java'
}
resources{
srcDir 'src/resources'
}
}
}
println sourceSets.main.java.srcDirs
println sourceSets['main'].resources.srcDirs
sourceSets{
println main.java.srcDirs
}
sourceSets{
main{
println java.srcDirs
}
}
sourceSets.all{
println name
}
~~~
根據實際操作來看,我們只是添加了一個java目錄和一個resources目錄。
~~~
D:\GRADLE~2\0112>gradle -q
[D:\gradle_product\0112\src\main\java, D:\gradle_product\0112\src\java]
[D:\gradle_product\0112\src\main\resources, D:\gradle_product\0112\src\resources
]
[D:\gradle_product\0112\src\main\java, D:\gradle_product\0112\src\java]
[D:\gradle_product\0112\src\main\java, D:\gradle_product\0112\src\java]
main
test
Welcome to Gradle 2.2.1.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
~~~
#### 設置sourcesets屬性

上面的表格列舉了一些sourceset重要的屬性,其中的一些屬性在之前的2個例子中也有涉及。
#### 定義新的sourceset屬性
~~~
apply plugin:'java'
sourceSets{
intTest
}
dependencies {
intTestCompile 'junit:junit:4.11'
intTestRuntime 'org.ow2.asm:asm-all:4.0'
}
~~~
在上面的代碼中,我們定義了一個新的屬性,叫做intTest,然后定義了2個依賴任務intTestCompile和intTestRunTime。這個我們在第5節.依賴管理中講過,sourceset的依賴管理中可以根據屬性值設置任務,剛好可以回過頭復習復習。執行下任務:
~~~
D:\GRADLE~2\0112>gradle intTestClasses
:compileIntTestJava UP-TO-DATE
:processIntTestResources UP-TO-DATE
:intTestClasses UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.699 secs
~~~
#### sourceset相關樣例
~~~
apply plugin:'java'
sourceSets{
intTest
}
dependencies {
intTestCompile 'junit:junit:4.11'
intTestRuntime 'org.ow2.asm:asm-all:4.0'
}
//將intTest輸出文件打成jar包
task intTestJar(type:Jar){
from sourceSets.intTest.output
}
//為intTest中所有的java文件生成java幫助文檔
task intTestJavadoc(type:Javadoc){
source sourceSets.intTest.allJava
}
//為intTest添加測試
task intTest(type:Test){
testClassesDir = sourceSets.intTest.output.classesDir
classpath = sourceSets.intTest.runtimeClasspath
}
~~~
首先我們執行intTest任務:
~~~
D:\GRADLE~2\0112>gradle intTestJar
:compileIntTestJava UP-TO-DATE
:processIntTestResources UP-TO-DATE
:intTestClasses UP-TO-DATE
:intTestJar
BUILD SUCCESSFUL
Total time: 4.337 secs
~~~
會在build/libs目錄下生成jar包

然后我們執行intTestJavadoc來生成java幫助文檔:
~~~
D:\GRADLE~2\0112>gradle intTestJavadoc
:intTestJavadoc UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.73 secs
~~~
執行成功,但是不會生成javadoc,因為我沒有定義intTest具體細節
最后來執行測試
~~~
D:\GRADLE~2\0112>gradle intTest
:compileIntTestJava UP-TO-DATE
:processIntTestResources UP-TO-DATE
:intTestClasses UP-TO-DATE
:intTest UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.793 secs
~~~
## 8.Javadoc
任務javadoc是Javadoc類的一個實例,支持核心java文檔選項和標準[doclet](http://unmi.cc/javadoc-customize-doclet/)格式,為了完整的繼承這些特性,gradle定義了2個類:CoreJavadocOptions和StandardJavadocDocletOptions。詳細信息也可以去這兩個類中去查查。
javadoc中的一些屬性:
**classpath**:執行環境,sourceSets.main.output代表的目錄,以及sourceSets.main.compileClasspath代表的目錄。是FileCollection的
**source**:源碼文件目錄,sourceSets.main.allJava代表的目錄,是FileTree類型的。
**destinationDir**:生成的文檔存放目錄
**title**:項目的版本和名稱
## 9.clean
該任務是Delete的一個實例,刪除用dir描述的目錄
## 10.Resources
是sourceset中的屬性,一般是通過Copy處理資源相關信息。會被ProcessResources用到:
ProcessResources.srcDirs引用的是sourceSet.resources的值。
ProcessResources.destinationDir引用的是sourceSet.output.resourcesDir的值。
## 11.CompileJava
java plugin為項目中的每一個sourceset都提供一個CompileJava對象實例。在腳本中是下面的樣式
~~~
apply plugin: 'java'
compileJava {
//enable compilation in a separate daemon process
options.fork = true
//enable incremental compilation
options.incremental = true
}
~~~
**classpath**:FileCollction,默認值是sourceSet.compileClasspath
**source**:FileTree,默認值是sourceSet.java
**destinationDir**:File.默認值是sourceSet.output.classesDir
## 12.增量式的java編譯
該功能正在孵化中,以后有可能更改。
該功能的主要目的是
1.避免在編譯了并不需要編譯的源文件,提高編譯的速度。
2.可能只是改變一點的輸出,并不需要重新編譯一些沒有任何改變的目錄。這一點對[JRebel](http://baike.baidu.com/link?url=JjWdQDfooN_XFDMP5Kd23QJX_T7qrzL-dKzc4OXp5aagOHyG0vUW1ofaf4GDOQvqj9OQ7qeroVAUDcsP4Jikb_)很有用。
這個功能肯定是一個高級且難以理解的東西,因為它涉及到底層的算法。所以我想我是不可能弄明白的了,且對我有啥用。只是知道有這么個東西就行。
## 13.Test
test任務是一個Test實例,它會自動識別和執行source set定義test目錄下所有的單元測試,而且會生成測試報告(這個好像挺爽的啊,看來測試驅動開發看能能很容易的實現啦)。
支持JUnit和TestNG。
#### 測試執行
測試的執行是獨立于JVM的,和構建的主進程也是分離的,其中關于jvm和運行時狀態屬性是可以通過API進行修改的。
1.你可以指定是否平行的執行測試。
2.你可以指定執行一定數量的case后重啟執行進程。
3.設置case失敗后的行為。
4.設置測試輸出的log的等級。
#### 調試
可以通過Test.getDebug屬性來讓jvm進入5005端口,進入調試模式。而且你可以通過命令行模式參數--debug -jvm進入debug模式。
#### 測試過濾
從gradle1.0開始,就具備了執行某些特殊的case,或者根據匹配模式刪選case來執行。可以做到以下幾點過濾:
1.依據測試方法的等級過濾,執行一個單一的測試。
2.依據自定義的注解(以后實現)
3.依據測試的層次,執行繼承某一個基礎類的測試(以后實現)
4.依據一些運行時的規則,例如一些特殊的系統屬性值或靜態狀態(以后實現)
說了這么多廢話,如果在腳本中定義過濾條件呢?
~~~
test {
filter{
//方法名
includeTestsMatching "*UiCheck"
//包名過濾
includeTestsMatching "org.gradle.internal.*"
//整合的case
includeTestsMatching "*IntegTest"
}
}
~~~
也可以通過gradle命令行的參數來過濾:

#### 根據系統屬性來執行單一測試

#### 測試檢測
gradle可以自動識別出哪些class是測試類,如果做到的呢,在編譯階段,gradle觀察這些編譯的java類。而掃描哪些文件夾里的類,你可以去設置,包括哪些文件,不包括哪些文件,都可以自定義。而且它也會掃描出用JUnit和TestNG框架寫的case。以JUnit為例來看看。
當使用JUnit的時候,我們會掃描junit3和junit4寫的case。
1.類或超類繼承與TestCase或者GroovyTestCase。
2.類或超類使用了@RunWith。
3.類或超類包含@Test注解的方法。
當使用TestNG的話,我們只掃描@Test注解的方法。
#### 測試分組
junit分組
~~~
test{
useJUnit{
includeCategories 'org.gradle.junit.CategoryA'
includeCategories 'org.gradle.junit.CategoryB'
}
}
~~~
TestNG分組
~~~
test{
useJUnit{
includeCategories 'org.gradle.junit.CategoryA'
includeCategories 'org.gradle.junit.CategoryB'
}
useTestNG{
excludeGroups 'integrationTests'
includeGroups 'unitTests'
}
}
~~~
#### 測試報告
gradle默認情況下生成下面3種報告:
1.HTML格式
2.XML格式
3.二進制
可以使用任務testReports來生成測試報告:
~~~
subprojects{
apply plugin:'java'
test{
reports.html.enabled = false
}
}
task testReport(type:TestReport){
destinationDir = file("$buildDir/report/allTest")
reportOn subprojects*.test
}
~~~
## 14.Jar任務
jar任務會將項目的源文件和資源文件打成jar包。
jar中manifest屬性,定義了jar包的版本和名稱。文件位于tmp//下:

- 前言
- gradle學習(1)-helloworld
- gradle學習(2)-基礎語法
- gradle學習(3)-基礎認識
- gradle學習(4)-構建java項目
- gradle學習(5)-創建eclipse項目
- gradle學習(6)-依賴管理
- gradle學習(7)-groovy
- gradle學習(8)-gradle的命令行
- gradle學習(9)-獲取build相關信息
- gradle學習(10)-gui
- gradle學習(11)-編寫構建腳本
- gradle學習(12)-groovy一些基礎語法
- gradle學習(13)-有的沒的
- gradle學習(14)-任務
- gradle學習(15)-任務
- gradle學習(16)-操作文件
- gradle學習(17)-被合并的ant
- gradle學習(18)-ant的屬性
- gradle學習(19)-log系統
- gradle學習(20)-詳解java插件
- gradle學習(21)-在eclipse中構建java項目
- gradle復習(1)-2種定義任務方式的區別
- gradle復習(2)-eclipse中添加依賴jar包
- gradle復習(3)-在gradle項目中使用TestNG
- gradle復習(4)-Cannot find System Java Compiler
- gradle復習(5)-Test remote debug
- gradle復習(6)-深入Jacoco
- gradle復習(7)-深入Jacoco
- gradle復習(8)-Task中行為
- gradle學習(22)-Sonar
- gradle學習(23)-Sonar runner