Java 插件是構建 JVM 項目的基礎,它為項目增加了很多能力,例如編譯,測試,打包,發佈等等。 很多插件都是基於 Java 插件實現的,例如 Android 插件。 ...
Java 插件是構建 JVM 項目的基礎,它為項目增加了很多能力,例如編譯,測試,打包,發佈等等。
很多插件都是基於 Java 插件實現的,例如 Android 插件。
用法
使用 id 應用插件
plugins {
id 'java'
}
Source sets 源集
Java 插件引入了源集的概念,它在邏輯上表示一組用於編譯執行的源文件,這些源文件可能包括源代碼文件和資源文件。
一個源集有一個相關聯的編譯類路徑和運行時類路徑。
Java 插件就是通過源集的概念來管理源代碼目錄的。
源集的一個用途是,把源文件進行邏輯上的分組,以描述它們的目的。
例如,你可能會使用一個源集來定義一個集成測試套件,或者你可能會使用單獨的源集來定義你的項目的 API 和實現類。
Java 插件提供了兩個標準源集
- main 包含了項目的源代碼,被用於編譯和生成 JAR 文件
- test 包含單元測試源代碼,它們將被編譯並使用 JUnit 或 TestNG 來執行。
源集提供了很多屬性,我這裡就列出幾個重要的屬性:
屬性 | 類型 | 預設值 | 描述 |
---|---|---|---|
name - 只讀 | String | 非空 | 源集的名字 |
output - 只讀 | SourceSetOutput | 非空 | 源集的輸出文件,包括它編譯過的類和資源。 |
output.classesDirs 只讀 | FileCollection | $buildDir/classes/java/$name 例如:build/classes/java/main |
源集編譯過的 class 文件目錄 |
output.resourcesDir 只讀 | File | $buildDir/resources/$name例如main源集:build/resources/main | 源集產生的資源目錄 |
java - 只讀 | SourceDirectorySet | [${project.projectDir}/src/${sourceSet.name}/java] | 源集的 Java 源代碼 ,只包含 .java 會排除其他類型。 |
java.srcDirs | Set |
src/$name/java, 例如 src/main/java |
源集的 Java 源文件的源目錄。是一個集合,可以設置多個源代碼目錄,更改源代碼目錄就是更改這個屬性 |
java.outputDir | File | $buildDir/classes/java/$name, e.g. build/classes/java/main |
源代碼編譯的 class 文件輸出目錄 |
resources - 只讀 | SourceDirectorySet | [${project.projectDir}/src/${sourceSet.name}/resources] | 源集的資源,只包含資源。 |
resources.srcDirs | Set |
[src/$name/resources] | 源集的資源目錄,是一個集合,可以指定多個 |
跟多的源集屬性可以查看下麵的文檔
定義一個新的源集
源集的位置也很重要,不要在 dependencies
下麵,否則對源集的依賴就將不起作用
sourceSets {
other
}
訪問源集
sourceSets 是 Java 插件為 Project 增加的一個屬性,可以直接使用。
task outSourceSet {
doLast {
//遍歷
sourceSets.all {
println "$name -> "
}
println "-----分割線----"
//單個的
println "${sourceSets.main.name} -> "
println "${sourceSets['main'].name} -> "
//一些屬性
println " java.srcDirs -->${sourceSets.main.java.srcDirs}"
println " resource.srcDirs -->${sourceSets.main.resources.srcDirs}"
}
}
為源集添加依賴
dependencies {
// This dependency is used by the application.
implementation 'com.google.guava:guava:27.1-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
//為 other 源集添加依賴
otherImplementation 'com.google.code.gson:gson:2.8.5'
}
將源集打成一個 JAR 包
創建一個 otherJar 任務,將源集的輸出作為任務的文件來源。
執行這個任務即可生成 JAR 包。
/**
* 為 other 源集打個 jar 包
* 預設輸出目錄是 build/libs
* 預設名字是 [archiveBaseName]-[archiveAppendix]-[archiveVersion]-[archiveClassifier].[archiveExtension]
*/
task otherJar(type:Jar){
archiveBaseName = sourceSets.other.name
archiveVersion = '0.1.0'
destinationDirectory = file("${project.projectDir}/jar")
from sourceSets.other.output
}
為源集生成 doc
創建一個任務將源集的所有 Java 文件作為源文件。
執行這個任務即可生成 doc 文件。
task otherDoc(type:Javadoc){
destinationDir = file("${project.projectDir}/doc")
source sourceSets.other.allJava
title sourceSets.other.name
}
項目結構
Java 插件的預設目錄結構如下所示, 無論這些文件夾中有沒有內容, Java 插件都會編譯裡面的內容, 並處理沒有的內容。
這個目錄結構也是 Java 世界標準的項目目錄。
目錄 | 描述 |
---|---|
src/main/java | Java 源文件目錄 |
src/main/resources | 資源文件目錄,例如 xml 和 properties 文件 |
src/test/java | Java 測試源文件目錄 |
src/test/resources | 測試資源目錄 |
src/sourceSet/java | 給定源集的源代碼目錄 |
src/sourceSet/resources | 給定源集的資源目錄 |
更改預設目錄
這裡以更改 main 源集的源代碼和資源目錄為例
sourceSets {
main {
java {
srcDirs = ['src/java']
}
resources {
srcDirs = ['src/resources']
}
}
}
增加的任務
Java 插件為 Project 增加了很多實用的任務,如下:
compileJava 類型是 JavaCompile
依賴於:所有參與編譯類路徑的任務,包括 jar 任務和通過項目依賴性在類路徑上的項目中的任務。
功能:使用 JDK 編譯器編譯生產 Java 源文件。processResources Copy
功能:複製生產資源到資源目錄classes
依賴:compileJava , processResources
這是個整合的任務,只是依賴於其他任務。其他插件可能會附加別的編譯任務到這裡。compileTestJava JavaCompile
依賴:classes, 以及有助於測試編譯類路徑的所有任務
功能:使用 JDK 編譯器編譯測試 Java 源代碼和資源文件processTestResources Copy
功能:複製測試資源到測試資源目錄testClasses
依賴:compileTestJava , processTestResources
這是個整合任務,只是依賴其他任務。其他擴展插件可能會將測試編譯任務附加到這裡。
jar Jar
依賴:classes
功能:根據主源集的類和資源,組裝生產 JAR 文件。javadoc JavaDoc
依賴:classes
功能:生成 API 文檔。
test Test
依賴:testClasses 以及生成測試運行時類路徑的所有任務
功能:使用 JUnit 或者 TestNG 運行單元測試
uploadArchives Upload
依賴:jar 以及生辰附加在 archives{} 配置里的構件的任何其他任務。
功能:上傳 archives{} 配置里的構件包含生成的 JAR 文件到配置的倉庫。
clean Delete
功能:刪除項目構建目錄
clean[TaskName] Delete
功能:刪除由指定任務生成的文件。例如 cleanJar 將刪除由 jar 任務產生的文件。
源集任務
你增加的每一個源集,Java 插件都會為它增加下麵列出的任務:
compilesourceSetJava JavaCompile
依賴:所有有助於源集編譯類路徑的任務。
功能:使用 JDK 編譯器編譯給定源集的 Java 源文件
processsourceSetResources Copy
功能:複製給定源集的資源到資源目錄
sourceSetClasses Task
依賴:compilesourceSetJava , processsourceSetResources
功能:準備給定的源集的類和資源以進行打包和執行。一些擴展插件可能會為給定源集附加編譯任務到這裡
生命周期任務
Java 插件將它的一些任務附加到基礎插件(Java插件自動應用)定義的生命周期任務上。
它還添加了一些其他的生命周期任務:
assemble
依賴:jar, 以及創建附加到歸檔配置的工件的所有其他任務。
彙總項目中所有歸檔的聚合任務。 這個任務是基礎插件(Base)里定義的。
check
依賴:test
彙總項目中的驗證任務,例如運行測試。一些插件會增加自己的驗證任務到這裡。這個任務是基礎插件(Base) 里定義的。
build
依賴:check, assemble
聚合執行項目完整構建的任務。這個任務是基礎插件(Base) 里定義的。
buildNeeded
依賴:build ,以及在testRuntimeClasspath配置中依賴的所有項目中的buildNeeded任務。
執行項目本身及其依賴的所有項目的完整構建。
buildDependents
依賴:build, 以及在 testRuntimeClasspath 配置中依賴此項目的所有項目的 buildDependents 任務
執行項目本身以及依賴於它的所有項目的完整構建。
buildConfigName -任務規則
依賴:生成附加到命名- ConfigName -配置的工件的所有任務
為指定的配置組裝工件。這個規則是在基礎插件增加的。
uploadConfigName -任務規則,類型:Upload
依賴:生成附加到命名- ConfigName -配置的工件的所有任務
在指定的配置里組裝和上傳構件。這個規則是在基礎插件增加的。
下麵的圖展示了這些任務的關係
依賴管理
Java 插件增加了很多依賴配置到項目中,JavaCompile 和 test 任務就可以使用這些配置將依賴文件添加到類路徑並使用他們。
依賴配置 | 描述 |
---|---|
編譯時依賴,被 implementation 取代 | |
implementation 繼承自compile | 僅實現依賴性。 |
compileOnly | 僅僅編譯時依賴 運行時不能用 |
compileClasspath 繼承自 compile,compileOnly,implemenation | 當編譯源代碼時使用的編譯類路徑,被 compileJava 任務使用 |
annotationProcessor | 編譯時使用的註解處理器 |
運行時依賴,由 runtimeOnly 取代 | |
runtimeOnly | 僅運行時依賴,編譯時不能用 |
runtimeClasspath 繼承自 runtimeOnly,runtime,implementation | 運行時類路徑包含 implementation 和僅運行時的元素 |
測試編譯的依賴項,被 testImplementation 取代 | |
testImplementation 繼承自 testCompile,implemenation | 僅實現測試依賴 |
testCompileOnly | 編譯時測試依賴,僅僅只在編譯時 |
testCompileClasspath 繼承自 testCompile ,testCompileOnly ,testImplementation | 測試編譯類路徑,當編譯測試代碼的時由 compileTestJava 任務使用 |
測試運行時依賴,由 testRuntimeOnly 取代 | |
testRuntimeOnly 繼承自 runtimeOnly | 測試的運行時依賴 |
testRuntimeClasspath 繼承自 testRuntimeOnly,testRuntime,testImplementation | 運行測試的運行時類路徑,由 test 任務使用 |
archives | 項目產生的構件(例如 jar),由 uploadArchives 使用 |
下麵兩張圖是 main 和 test 源集的配置依賴關係
- 灰色字體:已廢棄的
- 黑色字體綠色背景:可以根據配置聲明依賴項。
- 灰藍背景: 該配置用於被任務使用,而不是用於聲明依賴項。
- 淺藍色背景:任務
除了以上的配置,Java 插件為了每個源集還添加了以下配置,這些配置只針對給定源集
依賴配置 | 描述 |
---|---|
給定源集的編譯時依賴,由 sourceSet Implementation 取代 | |
sourceSet Implementation extend sourceSetCompile | 實現給定源集的依賴性。由 sourceSetCompileClasspath, sourceSetRuntimeClasspath 使用。 |
sourceSetCompileOnly | 給定源集的編譯時依賴,只能在編譯時使用。 |
sourceSetCompileClasspath extend compilesourceSetJava | 當編譯源代碼時的編譯類路徑,被 sourceSetCompile,sourceSetCompileOnly,sourceSetImplementation 使用。 |
sourceSetAnnotationProcessor | 給定源集在編譯時使用的註解處理器 |
給定源集的運行時依賴,由 sourceSetRuntimeOnly 取代 | |
sourceSetRuntimeOnly | 給定源集的運行時依賴,僅僅是運行時的 |
sourceSetRuntimeClasspath extends sourceSetRuntimeOnly ,sourceSetRuntime,sourceSetImplementation | 給定源集的運行時類路徑,包含 implement 和 runtime 的元素。 |
增加的屬性
Java 插件為項目增加了很多新的屬性,可以在腳本中直接使用這些屬性。
下麵是一些我認為比較重要的屬性:
屬性 | 類型 | 預設值 | 描述 |
---|---|---|---|
sourceSets 只讀 | SourceSetContainer | 非空 | 包含項目的源集 |
sourceCompatibility | JavaVersion | 當前 JVM 的版本 | 編譯 Java 源代碼時使用的 Java 版本,可以是一個 數值或者字元串,例如 '1.8' 或者 1.8 |
targetCompatibility | JavaVersion | sourceCompatibility | 生成 class 文件的版本,可以是一個 數值或者字元串,例如 '1.8' 或者 1.8 |
archivesBaseName | String | 歸檔的文件使用的名字,例如 JAR 和 ZIP 文件 | |
manifest | Manifest | 一個空的清單 | 包含所有 JAR 文件的清單。 |
libsDirName | String | libs | 項目生成的庫的存放目錄,項目的相對路徑。 |
更多的屬性可以查看文檔 Convention properties
學習資料:
- https://wiki.jikexueyuan.com/project/gradle/java-package.html
- http://benweizhu.github.io/blog/2015/01/31/deep-into-gradle-in-action-2/
- https://docs.gradle.org/current/userguide/java_plugin.html
- https://docs.gradle.org/current/userguide/building_java_projects.html