Java 外掛為專案新增 Java 編譯功能,以及測試和捆綁功能。它是許多其他 JVM 語言 Gradle 外掛的基礎。您可以在「建置 Java 專案」章節中找到 Java 外掛的完整介紹和概述。

如上所述,此外掛程式為使用 JVM 專案新增了基本建置區塊。它的功能集已被其他外掛程式取代,這些外掛程式根據您的專案類型提供更多功能。您應該研究 java-libraryapplication 外掛程式,或其中一個支援的替代 JVM 語言,而不是直接將其應用於您的專案。

用法

若要使用 Java 外掛,請在您的建置腳本中包含以下內容

build.gradle.kts
plugins {
    java
}
build.gradle
plugins {
    id 'java'
}

任務

Java 外掛為您的專案新增了許多任務,如下所示。

compileJavaJavaCompile

相依於:所有有助於編譯類別路徑的任務,包括來自透過專案相依性位於類別路徑上的專案的 jar 任務

使用 JDK 編譯器編譯生產 Java 原始碼檔案。

processResourcesProcessResources

將生產資源複製到生產資源目錄中。

classes

相依於compileJavaprocessResources

這是一個彙總任務,僅相依於其他任務。其他外掛程式可能會將其他編譯任務附加到它。

compileTestJavaJavaCompile

相依於classes,以及所有有助於測試編譯類別路徑的任務

使用 JDK 編譯器編譯測試 Java 原始碼檔案。

processTestResourcesCopy

將測試資源複製到測試資源目錄中。

testClasses

相依於compileTestJavaprocessTestResources

這是一個彙總任務,僅相依於其他任務。其他外掛程式可能會將其他測試編譯任務附加到它。

jarJar

相依於classes

根據附加到 main 原始碼集的類別和資源,組裝生產 JAR 檔案。

javadocJavadoc

相依於classes

使用 Javadoc 為生產 Java 原始碼產生 API 文件。

testTest

相依於testClasses,以及所有產生測試執行階段類別路徑的任務

使用 JUnit 或 TestNG 執行單元測試。

cleanDelete

刪除專案建置目錄。

cleanTaskNameDelete

刪除指定任務建立的檔案。例如,cleanJar 將刪除 jar 任務建立的 JAR 檔案,而 cleanTest 將刪除 test 任務建立的測試結果。

SourceSet 任務

對於您新增到專案的每個原始碼集,Java 外掛程式都會新增以下任務

compileSourceSetJavaJavaCompile

相依於:所有有助於原始碼集編譯類別路徑的任務

使用 JDK 編譯器編譯給定原始碼集的 Java 原始碼檔案。

processSourceSetResourcesCopy

將給定原始碼集的資源複製到資源目錄中。

sourceSetClassesTask

相依於compileSourceSetJavaprocessSourceSetResources

準備給定原始碼集的類別和資源以進行封裝和執行。某些外掛程式可能會為原始碼集新增其他編譯任務。

生命週期任務

Java 外掛程式將其某些任務附加到 Base 外掛程式 定義的生命週期任務(Java 外掛程式會自動應用 Base 外掛程式),並且它還新增了一些其他生命週期任務

assemble

相依於jar

彙總任務,用於組裝專案中的所有封存檔。此任務由 Base 外掛程式新增。

check

相依於test

彙總任務,用於執行驗證任務,例如執行測試。某些外掛程式會將其自己的驗證任務新增至 check。如果您希望自訂 Test 任務在完整建置中執行,也應該將其附加到此生命週期任務。此任務由 Base 外掛程式新增。

build

相依於checkassemble

彙總任務,用於執行專案的完整建置。此任務由 Base 外掛程式新增。

buildNeeded

相依於build,以及 testRuntimeClasspath 配置中所有相依專案的 buildNeeded 任務。

執行專案及其相依的所有專案的完整建置。

buildDependents

相依於build,以及在其 testRuntimeClasspath 配置中將此專案作為相依性的所有專案中的 buildDependents 任務

執行專案及其相依的所有專案的完整建置。

buildConfigName — 任務規則

相依於:產生附加到指定 — ConfigName — 配置的成品的所有任務

組裝指定配置的成品。此規則由 Base 外掛程式新增。

下圖顯示這些任務之間的關係。

javaPluginTasks
圖 1. Java 外掛程式 - 任務

專案佈局

Java 外掛程式假設專案佈局如下所示。這些目錄都不需要存在或包含任何內容。Java 外掛程式將編譯它找到的任何內容,並處理任何遺失的內容。

src/main/java

生產 Java 原始碼。

src/main/resources

生產資源,例如 XML 和屬性檔案。

src/test/java

測試 Java 原始碼。

src/test/resources

測試資源。

src/sourceSet/java

名為 sourceSet 的原始碼集的 Java 原始碼。

src/sourceSet/resources

名為 sourceSet 的原始碼集的資源。

變更專案佈局

您可以透過配置適當的原始碼集來配置專案佈局。以下章節將更詳細地討論此內容。以下是一個簡短範例,說明如何變更主要 Java 和資源原始碼目錄。

build.gradle.kts
sourceSets {
    main {
        java {
            setSrcDirs(listOf("src/java"))
        }
        resources {
            setSrcDirs(listOf("src/resources"))
        }
    }
}
build.gradle
sourceSets {
    main {
        java {
            srcDirs = ['src/java']
        }
        resources {
            srcDirs = ['src/resources']
        }
    }
}

原始碼集

此外掛程式新增了以下 原始碼集

main

包含專案的生產原始碼,這些原始碼會編譯並組裝成 JAR。

test

包含您的測試原始碼,這些原始碼會編譯並使用 JUnit 或 TestNG 執行。這些通常是單元測試,但您可以在此原始碼集中包含任何測試,只要它們都共用相同的編譯和執行階段類別路徑即可。

原始碼集屬性

下表列出原始碼集的一些重要屬性。您可以在 SourceSet 的 API 文件中找到更多詳細資訊。

name — (唯讀)String

原始碼集的名稱,用於識別它。

output — (唯讀)SourceSetOutput

原始碼集的輸出檔案,包含其編譯的類別和資源。

output.classesDirs — (唯讀)FileCollection

預設值layout.buildDirectory.dir("classes/java/$name"),例如 build/classes/java/main

將此原始碼集的類別產生到其中的目錄。可能包含其他 JVM 語言的目錄,例如 build/classes/kotlin/main

output.resourcesDir — File

預設值layout.buildDirectory.dir("resources/$name"),例如 build/resources/main

將此原始碼集的資源產生到其中的目錄。

compileClasspath — FileCollection

預設值${name}CompileClasspath 配置

編譯此原始碼集的原始碼檔案時要使用的類別路徑。

annotationProcessorPath — FileCollection

預設值${name}AnnotationProcessor 配置

編譯此原始碼集的原始碼檔案時要使用的處理器路徑。

runtimeClasspath — FileCollection

預設值$output${name}RuntimeClasspath 配置

執行此原始碼集的類別時要使用的類別路徑。

java — (唯讀)SourceDirectorySet

此原始碼集的 Java 原始碼檔案。僅包含在 Java 原始碼目錄中找到的 .java 檔案,並排除所有其他檔案。

java.srcDirs — Set<File>

預設值src/$name/java,例如 src/main/java

包含此原始碼集的 Java 原始碼檔案的原始碼目錄。您可以將其設定為 本節 中描述的任何值。

java.destinationDirectory — DirectoryProperty

預設值layout.buildDirectory.dir("classes/java/$name"),例如 build/classes/java/main

將編譯的 Java 原始碼產生到其中的目錄。您可以將其設定為 本節 中描述的任何值。

resources — (唯讀)SourceDirectorySet

此原始碼集的資源。僅包含資源,並排除在資源目錄中找到的任何 .java 檔案。其他外掛程式(例如 Groovy 外掛程式)會從此集合中排除其他檔案類型。

resources.srcDirs — Set<File>

預設值[src/$name/resources]

包含此原始碼集的資源的目錄。您可以將其設定為 本節 中描述的任何類型的值。

allJava — (唯讀)SourceDirectorySet

預設值:與 java 屬性相同

此原始碼集的所有 Java 檔案。某些外掛程式(例如 Groovy 外掛程式)會將其他 Java 原始碼檔案新增至此集合。

allSource — (唯讀)SourceDirectorySet

預設值resourcesjava 屬性中所有內容的總和

此原始碼集的所有語言的所有原始碼檔案。這包括所有資源檔案和所有 Java 原始碼檔案。某些外掛程式(例如 Groovy 外掛程式)會將其他原始碼檔案新增至此集合。

定義新的原始碼集

請參閱Java & JVM 專案中的測試章節中的 整合測試範例

其他一些簡單的原始碼集範例

新增包含原始碼集類別的 JAR

build.gradle.kts
tasks.register<Jar>("intTestJar") {
    from(sourceSets["intTest"].output)
}
build.gradle
tasks.register('intTestJar', Jar) {
    from sourceSets.intTest.output
}

為原始碼集產生 Javadoc

build.gradle.kts
tasks.register<Javadoc>("intTestJavadoc") {
    source(sourceSets["intTest"].allJava)
    classpath = sourceSets["intTest"].compileClasspath
}
build.gradle
tasks.register('intTestJavadoc', Javadoc) {
    source sourceSets.intTest.allJava
    classpath = sourceSets.intTest.compileClasspath
}

新增測試套件以在原始碼集中執行測試

build.gradle.kts
tasks.register<Test>("intTest") {
    testClassesDirs = sourceSets["intTest"].output.classesDirs
    classpath = sourceSets["intTest"].runtimeClasspath
}
build.gradle
tasks.register('intTest', Test) {
    testClassesDirs = sourceSets.intTest.output.classesDirs
    classpath = sourceSets.intTest.runtimeClasspath
}

相依性管理

Java 外掛程式為您的專案新增了許多 相依性配置,如下所示。然後,諸如 compileJavatest 之類的任務會使用一個或多個這些配置來取得對應的檔案並使用它們,例如將它們放在編譯或執行階段類別路徑上。

相依性配置

有關 defaultarchives 配置的資訊,請參閱 Base 外掛程式 參考文件。

有關 apicompileOnlyApi 配置的資訊,請參閱 Java 程式庫外掛程式 參考文件和 Java 專案的相依性管理

相依性宣告配置

implementation

代表專案主要原始碼集在編譯時和執行階段都需要的相依性(即,僅實作相依性)。

compileOnly

代表僅在編譯時需要且未包含在執行階段類別路徑中的相依性(即,僅編譯時相依性,執行階段未使用)。

runtimeOnly

代表僅在執行階段需要且未包含在編譯類別路徑中的相依性(即,僅在執行階段需要的相依性)。

testImplementation 擴充 implementation

代表專案測試原始碼集在編譯時和執行階段都需要的相依性(即,僅測試實作相依性)。

testCompileOnly

代表僅在專案測試原始碼集的編譯時需要且未包含在執行階段類別路徑中的相依性(即,僅用於編譯測試的其他相依性,執行階段未使用)。

testRuntimeOnly 擴充 runtimeOnly

代表僅在專案測試原始碼集的執行階段需要的相依性(即,用於執行測試的僅執行階段相依性)。

annotationProcessor

代表在專案原始碼編譯期間使用的註解處理器(即,在編譯期間使用的註解處理器)。

可解析的配置

compileClasspath 擴充 compileOnly, implementation

代表編譯主要原始碼時使用的類別路徑,其中包括來自 compileOnlyimplementation 配置的相依性。由任務 compileJava 使用。

runtimeClasspath 擴充 runtimeOnly, implementation

代表執行主要原始碼時使用的類別路徑,其中包括來自 runtimeOnlyimplementation 配置的相依性。由任務 run 使用。

testCompileClasspath 擴充 testCompileOnly, testImplementation

代表編譯測試原始碼時使用的類別路徑,其中包括來自 testCompileOnlytestImplementation 配置的相依性。由任務 compileTestJava 使用。

testRuntimeClasspath 擴充 testRuntimeOnly, testImplementation

代表執行測試原始碼時使用的類別路徑,其中包括來自 testRuntimeOnlytestImplementation 配置的相依性。由任務 test 使用。

下圖分別顯示 maintest 原始碼集的相依性配置。您可以使用此圖例來解讀顏色

  • 藍色背景 — 您可以針對配置宣告相依性。

  • 綠色背景 — 配置供任務使用,而不是供您宣告相依性。

  • 灰色背景 — 任務。

java main configurations
圖 2. Java 外掛程式 - main 原始碼集相依性配置
java test configurations
圖 3. Java 外掛程式 - test 原始碼集相依性配置

對於您新增到專案的每個原始碼集,Java 外掛程式都會新增以下相依性配置

SourceSet 相依性配置

sourceSetImplementation

給定原始碼集的編譯時相依性。由 sourceSetCompileClasspath, sourceSetRuntimeClasspath 使用。

sourceSetCompileOnly

給定原始碼集的僅編譯時相依性,執行階段未使用。

sourceSetCompileClasspath 擴充 sourceSetCompileOnly, sourceSetImplementation

編譯類別路徑,在編譯原始碼時使用。由 compileSourceSetJava 使用。

sourceSetAnnotationProcessor

在此原始碼集編譯期間使用的註解處理器。

sourceSetRuntimeOnly

給定原始碼集的僅執行階段相依性。

sourceSetRuntimeClasspath 擴充 sourceSetRuntimeOnly, sourceSetImplementation

執行階段類別路徑包含實作的元素,以及僅執行階段元素。

貢獻的擴充功能

Java 外掛程式將 java 擴充功能 新增至專案。這允許在專用的 DSL 區塊內配置許多與 Java 相關的屬性。

build.gradle.kts
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}
build.gradle
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

以下是 java 擴充功能內可用的屬性和 DSL 函數列表,以及簡短說明。

工具鏈和相容性

toolchain

Java 工具鏈,供使用 JVM 工具的任務使用,例如編譯和執行。預設值:建置 JVM 工具鏈。

JavaVersion sourceCompatibility

編譯 Java 原始碼時要使用的 Java 版本相容性。預設值:來自此外掛程式的工具鏈的語言版本。
請注意,在大多數情況下,使用 工具鏈 比使用相容性設定更佳。

JavaVersion targetCompatibility

要為其產生類別的 Java 版本。預設值:sourceCompatibility
請注意,在大多數情況下,使用 工具鏈 比使用相容性設定更佳。

封裝

withJavadocJar()

自動封裝 Javadoc 並建立具有成品 -javadoc.jar 的變體 javadocElements,這將是發布的一部分。

withSourcesJar()

自動封裝原始碼並建立具有成品 -sources.jar 的變體 sourceElements,這將是發布的一部分。

目錄屬性

String reporting.baseDir

要將報告產生到其中的目錄名稱,相對於建置目錄。預設值:reports

(唯讀)File reportsDir

要將報告產生到其中的目錄。預設值:reporting.baseDirectory

String testResultsDirName

要將測試結果 .xml 檔案產生到其中的目錄名稱,相對於建置目錄。預設值:test-results

(唯讀)File testResultsDir

要將測試結果 .xml 檔案產生到其中的目錄。預設值:layout.buildDirectory.dir(testResultsDirName)

String testReportDirName

要將測試報告產生到其中的目錄名稱,相對於報告目錄。預設值:tests

(唯讀)File testReportDir

要將測試報告產生到其中的目錄。預設值:reportsDir/testReportDirName

String libsDirName

要將程式庫產生到其中的目錄名稱,相對於建置目錄。預設值:libs

(唯讀)File libsDir

要將程式庫產生到其中的目錄。預設值:layout.buildDirectory.dir(libsDirName)

String distsDirName

要將發行版本產生到其中的目錄名稱,相對於建置目錄。預設值:distributions

(唯讀)File distsDir

要將發行版本產生到其中的目錄。預設值:layout.buildDirectory.dir(distsDirName)

String docsDirName

要將文件產生到其中的目錄名稱,相對於建置目錄。預設值:docs

(唯讀)File docsDir

要將文件產生到其中的目錄。預設值:layout.buildDirectory.dir(docsDirName)

String dependencyCacheDirName

要快取原始碼相依性資訊的目錄名稱,相對於建置目錄。預設值:dependency-cache

其他屬性

(唯讀)SourceSetContainer sourceSets

包含專案的原始碼集。預設值:非空值 SourceSetContainer

String archivesBaseName

用於封存檔(例如 JAR 或 ZIP 檔案)的基本名稱。預設值:projectName

Manifest manifest

要包含在所有 JAR 檔案中的 manifest。預設值:空的 manifest。

慣例屬性(已棄用)

Java 外掛程式為專案新增了許多慣例屬性。您可以在建置腳本中使用這些屬性,就像它們是專案物件的屬性一樣。這些屬性已棄用,並由上述擴充功能取代。請參閱 JavaPluginConvention DSL 文件,以取得有關它們的資訊。

測試

有關更多詳細資訊,請參閱「Java & JVM 專案中的測試」章節。

發布

components.java

用於發布jar 任務建立的生產 JAR 的 SoftwareComponent。此元件包含 JAR 的執行階段相依性資訊。

另請參閱 java 擴充功能

增量 Java 編譯

Gradle 隨附一個複雜的增量 Java 編譯器,預設為啟用狀態。

這為您帶來以下好處

  • 增量建置速度更快。

  • 變更的類別檔案數量盡可能少。不需要重新編譯的類別在輸出目錄中保持不變。當使用 JRebel 時,這是一個非常有用的範例情境 — 變更的輸出類別越少,JVM 可以使用刷新的類別就越快。

為了幫助您了解增量編譯的工作原理,以下提供高階概述

  • Gradle 將重新編譯所有受變更影響的類別。

  • 如果類別已變更,或者它相依於另一個受影響的類別,則該類別將會受到影響。無論另一個類別是在同一個專案、另一個專案還是外部程式庫中定義,這都有效。

  • 類別的相依性是從其位元組碼中的類型參考或透過編譯器外掛程式的符號分析來判斷的。

  • 由於來源保留註解在位元組碼中不可見,因此變更來源保留註解將導致完整重新編譯。

  • 您可以透過應用良好的軟體設計原則(例如鬆散耦合)來提升增量編譯效能。例如,如果您在具體類別及其相依項之間放置一個介面,則只有在介面變更時才會重新編譯相依類別,而在實作變更時則不會重新編譯。

  • 類別分析快取在專案目錄中,因此在全新簽出後第一次建置可能會較慢。請考慮在您的建置伺服器上關閉增量編譯器。

  • 類別分析也是儲存在建置快取中的輸出,這表示如果從建置快取擷取編譯輸出,則也會擷取增量編譯分析,並且下一次編譯將是增量的。

已知問題

  • 如果您使用的註解處理器會讀取資源(例如配置檔案),則需要將這些資源宣告為編譯任務的輸入。

  • 如果資源檔案已變更,Gradle 將觸發完整重新編譯。

  • 使用自訂 executablejavaHome 會停用某些最佳化。編譯任務在編譯錯誤後或 Java 常數變更時不會立即使用增量建置。如果可能,請改用 工具鏈

  • 具有與套件名稱不符的原始碼結構(雖然編譯是合法的)可能會在工具鏈中造成問題。如果涉及註解處理和 快取,則更是如此。

增量註解處理

從 Gradle 4.7 開始,增量編譯器也支援增量註解處理。所有註解處理器都需要選擇加入此功能,否則它們將觸發完整重新編譯。

身為使用者,您可以在 --info 記錄檔中查看哪些註解處理器正在觸發完整重新編譯。如果在編譯任務中設定了自訂的 executablejavaHome,則會停用增量註解處理。

使註解處理器支援增量編譯

請先查看增量 Java 編譯,因為增量註解處理是建立在其基礎之上的。

Gradle 支援兩種常見的註解處理器類別的增量編譯:「隔離式」和「聚合式」。請查閱以下資訊,以決定哪個類別適合您的處理器。

然後,您可以使用處理器 META-INF 目錄中的檔案,為增量編譯註冊您的處理器。格式為每行一個處理器,以逗號分隔處理器類別的完整名稱及其不區分大小寫的類別。

範例:註冊增量註解處理器

processor/src/main/resources/META-INF/gradle/incremental.annotation.processors
org.gradle.EntityProcessor,isolating
org.gradle.ServiceRegistryProcessor,dynamic

如果您的處理器只能在執行時決定是否為增量式,您可以在 META-INF 描述符中將其宣告為「dynamic」,並使用 Processor#getSupportedOptions() 方法在執行時傳回其真實類型。

範例:動態註冊增量註解處理器

processor/src/main/java/org/gradle/ServiceRegistryProcessor.java
@Override
public Set<String> getSupportedOptions() {
    return Collections.singleton("org.gradle.annotation.processing.aggregating");
}

這兩種類別都有以下限制

  • 它們只能讀取 CLASSRUNTIME 保留策略的註解。

  • 如果使用者傳遞 -parameters 編譯器引數,它們才能讀取參數名稱。

  • 它們必須使用 Filer API 產生其檔案。以任何其他方式寫入檔案將導致稍後的靜默失敗,因為這些檔案將無法正確清除。如果您的處理器執行此操作,則它不能是增量式的。

  • 它們不得依賴於編譯器特定的 API,例如 com.sun.source.util.Trees。Gradle 包裝了處理 API,因此嘗試轉換為編譯器特定類型將會失敗。如果您的處理器執行此操作,則它不能是增量式的,除非您有某些回退機制。

  • 如果它們使用 Filer#createResource,則 location 引數必須是 StandardLocation 中的這些值之一:CLASS_OUTPUTSOURCE_OUTPUTNATIVE_HEADER_OUTPUT。任何其他引數都會停用增量處理。

「隔離式」註解處理器

這是最快的類別,它們獨立查看每個帶註解的元素,為其建立產生的檔案或驗證訊息。例如,EntityProcessor 可以為每個使用 @Entity 註解的類型建立 <TypeName>Repository

範例:隔離式註解處理器

processor/src/main/java/org/gradle/EntityProcessor.java
Set<? extends Element> entities = roundEnv.getElementsAnnotatedWith(entityAnnotation);
for (Element entity : entities) {
    createRepository((TypeElement) entity);
}

「隔離式」處理器具有以下額外限制

  • 它們必須根據可從其 AST 存取到的資訊,為帶註解的類型做出所有決策(程式碼產生、驗證訊息)。這表示您可以分析類型的父類別、方法傳回類型、註解等,甚至是遞移地分析。但是,您不能根據 RoundEnvironment 中不相關的元素做出決策。這樣做將導致靜默失敗,因為稍後重新編譯的檔案太少。如果您的處理器需要根據不相關元素的組合做出決策,請將其標記為「聚合式」。

  • 它們必須為使用 Filer API 產生的每個檔案提供正好一個原始元素。如果提供零個或多個原始元素,Gradle 將重新編譯所有原始碼檔案。

當重新編譯原始碼檔案時,Gradle 將重新編譯從其產生的所有檔案。當刪除原始碼檔案時,將刪除從其產生的檔案。

「聚合式」註解處理器

這些處理器可以將多個原始碼檔案聚合到一個或多個輸出檔案或驗證訊息中。例如,ServiceRegistryProcessor 可以建立一個單一的 ServiceRegistry,其中每個使用 @Service 註解的類型都有一個方法。

範例:聚合式註解處理器

processor/src/main/java/org/gradle/ServiceRegistryProcessor.java
JavaFileObject serviceRegistry = filer.createSourceFile("ServiceRegistry");
Writer writer = serviceRegistry.openWriter();
writer.write("public class ServiceRegistry {");
for (Element service : roundEnv.getElementsAnnotatedWith(serviceAnnotation)) {
    addServiceCreationMethod(writer, (TypeElement) service);
}
writer.write("}");
writer.close();

Gradle 將始終重新處理(但不會重新編譯)處理器已註冊的所有帶註解的檔案。Gradle 將始終重新編譯處理器產生的任何檔案。

許多熱門的註解處理器都支援增量註解處理(請參閱下表)。請直接與註解處理器專案確認以取得最新的資訊和文件。
註解處理器 開始支援的版本 詳細資訊

不適用

不適用

部分支援。

不適用

不適用

DataBinding

隱藏在功能切換開關後面

Dagger

2.18 功能切換開關支援,2.24 預設啟用

kapt

隱藏在功能切換開關後面

Toothpick

2.0

不適用

Glide

不適用

Android-State

不適用

Parceler

不適用

Dart 和 Henson

不適用

不適用

不適用

不適用

Requery

不適用

不適用

EclipseLink

不適用

不適用

Immutables

不適用

2.2.0 功能切換開關支援,2.3.0-alpha02 預設啟用

不適用

不適用

DBFlow

不適用

AndServer

不適用

不適用

2.0

不適用

不適用

不適用

隱藏在功能切換開關後面

不適用

避免編譯

如果相依專案以 ABI 相容的方式變更(僅變更其私有 API),則 Java 編譯任務將是最新的。這表示如果專案 A 相依於專案 B,並且 B 中的類別以 ABI 相容的方式變更(通常僅變更方法的主體),則 Gradle 將不會重新編譯 A

以下是一些不影響公用 API 並被忽略的變更類型

  • 變更方法主體

  • 變更註解

  • 新增、移除或變更私有方法、欄位或內部類別

  • 新增、移除或變更資源

  • 變更類別路徑中 jar 檔或目錄的名稱

  • 重新命名參數

由於實作細節對於註解處理器很重要,因此必須在註解處理器路徑上單獨宣告它們。Gradle 會忽略編譯類別路徑上的註解處理器。

build.gradle.kts
dependencies {
    // The dagger compiler and its transitive dependencies will only be found on annotation processing classpath
    annotationProcessor("com.google.dagger:dagger-compiler:2.44")

    // And we still need the Dagger library on the compile classpath itself
    implementation("com.google.dagger:dagger:2.44")
}
build.gradle
dependencies {
    // The dagger compiler and its transitive dependencies will only be found on annotation processing classpath
    annotationProcessor 'com.google.dagger:dagger-compiler:2.44'

    // And we still need the Dagger library on the compile classpath itself
    implementation 'com.google.dagger:dagger:2.44'
}

變體感知選擇

整套 JVM 外掛程式利用 變體感知解析 來處理使用的相依性。它們還安裝了一組屬性相容性和消除歧義規則,以 設定 Gradle 屬性 以符合 JVM 生態系統的特性。