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 來源檔案。

processSourceSetResources複製

將給定來源設定的資源複製到資源目錄中。

sourceSetClasses任務

依賴於compileSourceSetJavaprocessSourceSetResources

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

生命週期任務

Java 外掛程式會將某些任務附加到 基本外掛程式 定義的生命週期任務(Java 外掛程式會自動套用)上,同時也會新增幾個其他生命週期任務

組建

依賴於jar

彙總專案中所有檔案的彙總任務。此任務由基本外掛程式新增。

檢查

依賴於測試

執行驗證任務(例如執行測試)的彙總任務。某些外掛程式會將自己的驗證任務新增到 檢查。如果您希望自訂 測試 任務在完整建置中執行,也應該將它們附加到此生命週期任務。此任務由基本外掛程式新增。

建置

依賴於檢查組建

執行專案完整建置的彙總任務。此任務由基本外掛程式新增。

buildNeeded

依賴於建置,以及 testRuntimeClasspath 組態中所有專案的 buildNeeded 任務。

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

buildDependents

依賴於建置,以及所有專案的 buildDependents 任務,這些專案在 testRuntimeClasspath 組態中將此專案設為依賴項

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

buildConfigName — 任務規則

依賴於:所有產生附加到命名(ConfigName)組態的成品的任務

彙總指定組態的成品。此規則由基本外掛程式新增。

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

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 設定的資訊,請參閱 基本外掛程式 參考文件。

如需 apicompileOnlyApi 設定的資訊,請參閱 Java 函式庫外掛程式 參考文件和 Java 專案的相依性管理

implementation

僅實作相依性。

compileOnly

僅編譯時間相依性,在執行時期不使用。

compileClasspath 延伸 compileOnly, implementation

編譯類別路徑,在編譯來源時使用。由 compileJava 任務使用。

annotationProcessor

編譯期間使用的註解處理器。

runtimeOnly

僅限執行時期的依賴項。

runtimeClasspath 延伸 runtimeOnly, implementation

執行時期類別路徑包含實作的元素,以及僅限執行時期的元素。

testImplementation 延伸 implementation

僅限測試的實作依賴項。

testCompileOnly

僅限編譯測試的額外依賴項,不會在執行時期使用。

testCompileClasspath 延伸 testCompileOnly, testImplementation

測試編譯類別路徑,用於編譯測試來源時。由工作 compileTestJava 使用。

testRuntimeOnly 延伸 runtimeOnly

僅限執行時期的依賴項,用於執行測試。

testRuntimeClasspath 延伸 testRuntimeOnly, testImplementation

執行測試的執行時期類別路徑。由工作 test 使用。

下列圖表分別顯示 主要測試 來源組的依賴項設定。您可以使用此圖例來詮釋顏色

  • 綠色背景 — 您可以針對設定宣告依賴項。

  • 藍灰色背景 — 此設定供工作使用,您不能用來宣告依賴項。

  • 淺藍色背景,搭配等寬字體 — 工作。

java main configurations
圖 2. Java 外掛程式 - 主要 來源組依賴項設定
java test configurations
圖 3. Java 外掛程式 - 測試 來源組依賴項設定

對於您新增到專案的每個來源組,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)

字串 distsDirName

產生發行版的目錄名稱,相對於建置目錄。預設值:distributions

(唯讀) 檔案 distsDir

產生發行版的目錄。預設值:layout.buildDirectory.dir(distsDirName)

字串 docsDirName

產生文件檔的目錄名稱,相對於建置目錄。預設值:docs

(唯讀) 檔案 docsDir

產生文件檔的目錄。預設值:layout.buildDirectory.dir(docsDirName)

字串 dependencyCacheDirName

快取來源依賴資訊的目錄名稱,相對於建置目錄。預設值:dependency-cache

其他屬性

(唯讀) SourceSetContainer sourceSets

包含專案的來源組。預設值:非 Null SourceSetContainer

字串 archivesBaseName

用於檔案的基礎名稱,例如 JAR 或 ZIP 檔案。預設值:projectName

Manifest manifest

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

慣例屬性 (已棄用)

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 描述符中將其宣告為「動態」,並在執行階段使用 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#createResourcelocation 參數必須是 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 and 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 生態系統的特定事項。