本章節提供您將較舊的 Gradle 4.x 建置遷移到 Gradle 5.0 所需的資訊。在大多數情況下,您需要套用從您升級的版本之後的所有版本中的變更。例如,如果您從 Gradle 4.3 升級到 5.0,您還需要套用自 4.4、4.5 等直到 5.0 的變更。

如果您將 Gradle 用於 Android,您需要將 Android Gradle 外掛程式和 Android Studio 都升級到 3.3 或更高版本。

適用於所有使用者

  1. 如果您尚未升級到最新的 4.10.x 版本,請閱讀以下 章節,以取得將您的專案升級到最新的 4.10.x 版本的協助。我們建議升級到最新的 4.10.x 版本,以便在升級到 5.0 之前獲得最有用的警告和棄用資訊。為了簡化潛在問題的疑難排解,請避免同時升級 Gradle 和遷移到 Kotlin DSL。

  2. 嘗試執行 gradle help --scan 並檢視產生的建置掃描的棄用檢視。如果沒有警告,「棄用」索引標籤將不會出現。

    Deprecations View of a Gradle Build Scan

    這樣您就可以看到適用於您建置的任何棄用警告。如果您嘗試直接升級到 Gradle 5.x,它會產生(可能不太明顯的)錯誤。

    或者,您可以執行 gradle help --warning-mode=all 以在主控台中查看棄用,但它可能不會報告那麼詳細的資訊。

  3. 更新您的外掛程式。

    某些外掛程式會因這個新版本的 Gradle 而中斷,例如,因為它們使用已移除或變更的內部 API。先前的步驟將透過在外掛程式嘗試使用已棄用的 API 部分時發出棄用警告,來協助您識別潛在問題。

    特別是,您需要使用至少 2.x 版本的 Shadow Plugin

  4. 執行 gradle wrapper --gradle-version 5.0 以將專案更新到 5.0

  5. 如果您尚未升級到 Java 8 或更高版本,請升級。Gradle 4.x 需要 Java 7,而 Gradle 5 需要 Java 8 才能執行。

  6. 閱讀 從 4.10 升級 章節並進行任何必要的變更。

  7. 嘗試執行專案並使用疑難排解指南偵錯任何錯誤。

此外,Gradle 還新增了幾項重要的全新和改良功能,您應該考慮在您的建置中使用這些功能

其他需要注意的重大變更可能會中斷您的建置,包括

從 4.10 及更早版本升級

如果您尚未升級到 4.10 版本,請跳到適用於您目前 Gradle 版本的章節,然後逐步升級直到到達這裡。然後,在從 Gradle 4.10 升級到 5.0 時套用這些變更。

其他變更

  • 不再需要 enableFeaturePreview('IMPROVED_POM_SUPPORT')enableFeaturePreview('STABLE_PUBLISHING') 標記。這些功能現在預設為啟用。

  • Gradle 現在為 Java 9 及更高版本捆綁了 JAXB。您可以從 org.gradle.jvmargs 中移除 --add-modules java.xml.bind 選項(如果已設定)。

潛在的重大變更

本節中的變更可能會中斷您的建置,但絕大多數變更已被棄用相當長一段時間,並且很少有建置會受到其中大量變更的影響。我們強烈建議您先升級到 Gradle 4.10,以取得有關哪些棄用會影響您的建置的報告。

以下重大變更並非來自棄用,而是行為變更的結果

以下重大變更將以 Gradle 4.10 的棄用警告形式出現

一般
  • 用於任務定義的 << 不再運作。換句話說,您不能使用語法 task myTask << { …​ }

    請改用 Task.doLast() 方法,如下所示

    task myTask {
        doLast {
            ...
        }
    }
  • 您不能再在網域物件名稱(例如專案和任務名稱)中使用以下任何字元:<space> / \ : < > " ? * | 。您也不應使用 . 作為開頭或結尾字元。

執行 Gradle 和建置環境
  • 如前所述,Gradle 無法再在 Java 7 上執行。但是,您仍然可以使用 forked 編譯和測試 來建置和測試適用於 Java 6 及更高版本的軟體。

  • -Dtest.single 命令列選項已移除 — 請改用 測試篩選

  • -Dtest.debug 命令列選項已移除 — 請改用 --debug-jvm 選項

  • -u/--no-search-upward 命令列選項已移除 — 請確保您的所有建置都有 settings.gradle 檔案。

  • --recompile-scripts 命令列選項已移除。

  • 除非巢狀建置具有 settings.gradle 檔案,否則您不能再在另一個 Gradle 建置的子目錄中巢狀 Gradle 建置。

  • DirectoryBuildCache.setTargetSizeInMB(long) 方法已移除 — 請改用 DirectoryBuildCache.removeUnusedEntriesAfterDays

  • org.gradle.readLoggingConfigFile 系統屬性不再執行任何操作 — 請更新受影響的測試,以使用您的 java.util.logging 設定。

使用檔案
  • 您不能再使用 as 關鍵字或 asType() 方法將 FileCollection 物件轉換為其他類型。

  • 您不能再將 null 作為 CopySpec.from(Object, Action) 的配置動作傳遞。

  • 為了更好地與 Kotlin DSL 相容,CopySpec.duplicatesStrategy 不再可為 null。屬性設定器不再接受 null 作為將屬性重設回其預設值的方式。請改用 DuplicatesStrategy.INHERIT

  • FileCollection.stopExecutionIfEmpty() 方法已移除 — 請改為在 FileCollection 任務屬性上使用 @SkipWhenEmpty 註解。

  • FileCollection.add() 方法已移除 — 請使用 Project.files()Project.fileTree() 來建立可配置的檔案集合/檔案樹狀結構,並透過 ConfigurableFileCollection.from() 將其新增至其中。

  • SimpleFileCollection 已移除 — 請改用 Project.files(Object…​)

  • 請勿讓您自己的類別擴充 AbstractFileCollection — 請改用 Project.files() 方法。此問題可能會顯示為缺少 getBuildDependencies() 方法。

Java 建置
任務和屬性
  • 以下與 延遲屬性 相關的舊版類別和方法已移除 — 請使用 ObjectFactory.property() 來建立 Property 實例

    • PropertyState

    • DirectoryVar

    • RegularFileVar

    • ProjectLayout.newDirectoryVar()

    • ProjectLayout.newFileVar()

    • Project.property(Class)

    • Script.property(Class)

    • ProviderFactory.property(Class)

  • 使用 任務配置避免 API 配置和註冊的任務對可以從配置動作呼叫的其他方法有更多限制。

  • 內部 @Option@OptionValues 註解 — 套件 org.gradle.api.internal.tasks.options — 已移除。請改用公用 @Option@OptionValues 註解。

  • Task.deleteAllActions() 方法已移除,沒有替代方法。

  • Task.dependsOnTaskDidWork() 方法已移除 — 請改用 宣告的輸入和輸出

  • TaskInternal 的以下屬性和方法已移除 — 請使用任務相依性、任務規則、可重複使用的公用程式方法或 Worker API 來取代直接執行任務。

    • execute()

    • executer

    • getValidators()

    • addValidator()

  • TaskInputs.file(Object) 方法不能再使用解析為單一常規檔案以外的任何內容的引數呼叫。

  • TaskInputs.dir(Object) 方法不能再使用解析為單一目錄以外的任何內容的引數呼叫。

  • 您不能再透過 TaskInputsTaskOutputs 註冊無效的輸入和輸出。

  • TaskDestroyables.file()TaskDestroyables.files() 方法已移除 — 請改用 TaskDestroyables.register()

  • SimpleWorkResult 已移除 — 請使用 WorkResult.didWork

  • 覆寫 在 4.8 中棄用的內建任務現在會產生錯誤。

    嘗試取代內建任務將會產生類似以下的錯誤

    > Cannot add task 'wrapper' as a task with that name already exists.
Scala 和 Play
  • 不再支援 Play 2.2 — 請升級您正在使用的 Play 版本。

  • ScalaDocOptions.styleSheet 屬性已移除 — Scala 2.11.8 及更高版本中的 Scaladoc Ant 任務不再支援此屬性。

Kotlin DSL
  • 構件配置存取器現在具有 NamedDomainObjectProvider<Configuration> 類型,而不是 Configuration

  • PluginAware.apply<T>(to) 已重新命名為 PluginAware.applyTo<T>(target)

這兩項變更都可能導致腳本編譯錯誤。請參閱 Gradle Kotlin DSL 發行說明,以取得更多資訊以及如何修復因上述變更而中斷的建置。

其他
  • ConfigurableReport.setDestination(Object) 方法已移除 — 請改用 ConfigurableReport.setDestination(File)

  • Signature.setFile(File) 方法已移除 — Gradle 不支援變更產生簽名的輸出檔案。

  • 唯讀 Signature.toSignArtifact 屬性已移除 — 它不應成為公用 API 的一部分。

  • @DeferredConfigurable 註解已移除。

  • 方法 isDeferredConfigurable() 已從 ExtensionSchema 中移除。

  • IdeaPlugin.performPostEvaluationActions()EclipsePlugin.performPostEvaluationActions() 已移除。

  • BroadcastingCollectionEventRegister.getAddAction() 方法已移除,沒有替代方法。

  • 預設情況下,不再匯入內部 org.gradle.util 套件。

    理想情況下,您不應使用此套件中的類別,但作為快速修復,您可以為這些類別將明確的匯入新增到您的建置腳本。

  • gradlePluginPortal() 儲存庫 預設不再尋找沒有 POM 的 JAR

  • Tooling API 無法再連線到使用低於 Gradle 2.6 的 Gradle 版本建置。這同樣適用於透過 TestKit 執行的建置。

  • Gradle 5.0 需要最低 Tooling API 用戶端版本 3.0。較舊的用戶端程式庫無法再使用 Gradle 5.0 執行建置。

  • IdeaModule Tooling API 模型元素包含用於擷取資源和測試資源的方法,因此這些元素已從 IdeaModule.getSourceDirs()IdeaModule.getTestSourceDirs() 的結果中移除。

  • 在先前的 Gradle 版本中,子類別可以存取 SourceTask 中的 source 欄位。現在情況並非如此,因為 source 欄位現在宣告為 private

  • 在 Worker API 中,worker 的工作目錄不能再設定

  • 相依性和版本約束相關的行為變更可能會影響少數使用者。

  • DefaultTask 上的屬性工廠方法發生了一些變更,可能會影響自訂任務的建立。

從 4.9 及更早版本升級

如果您尚未升級到 4.9 版本,請跳到適用於您目前 Gradle 版本的章節,然後逐步升級直到到達這裡。然後,在升級到 Gradle 4.10 時套用這些變更。

已棄用的類別、方法和屬性

請遵循 API 連結以了解如何處理這些棄用(如果此處未提供額外資訊)

潛在的重大變更

從 4.8 及更早版本升級

潛在的重大變更

從 4.7 及更早版本升級

潛在的重大變更

  • 如果找不到指定的 init 腳本,建置現在將會失敗。

  • TaskContainer.remove() 現在會確實移除指定的任務 — 某些外掛程式可能不小心依賴了舊的行為。

  • Gradle 現在會遵循 Maven POM 排除項目中隱含的萬用字元.

  • Kotlin DSL 現在會遵循 JSR-305 套件註解。

    這會導致根據 JSR-305 註解的某些類型會被視為可為 Null,而之前則被視為不可為 Null。這可能會導致組建腳本中出現編譯錯誤。請參閱相關的 Kotlin DSL 版本發行說明以取得詳細資訊。

  • 除非主控台同時連接到標準輸出和標準錯誤,否則錯誤訊息現在會導向標準錯誤,而不是標準輸出。這可能會影響到抓取組建純文字主控台輸出的工具。如果您是從較舊版本的 Gradle 升級,請忽略此變更。

已棄用

在此版本之前,組建允許取代內建任務。此功能已被棄用

不應被取代的完整內建任務列表為:wrapperinithelptasksprojectsbuildEnvironmentcomponentsdependenciesdependencyInsightdependentComponentsmodelproperties

從 4.6 及更早版本升級

潛在的重大變更

  • Gradle 現在會依照慣例,在根專案的 config/checkstyle 目錄中尋找 Checkstyle 設定檔。

    子專案中的 Checkstyle 設定檔 — 舊的慣例位置 — 將被忽略,除非您透過 checkstyle.configDircheckstyle.config 明確設定其路徑。

  • Gradle 的純文字主控台輸出結構已變更,這可能會破壞抓取該輸出的工具。

  • 許多與編譯、連結和安裝相關的原生任務的 API 已發生重大變更

  • [Kotlin DSL] 用於存取 Gradle 組建屬性的委派屬性 — 例如在 gradle.properties 中定義的屬性 — 現在必須明確指定類型。

  • [Kotlin DSL] 在巢狀範圍內宣告 plugins {} 區塊現在會擲回例外狀況。

  • [Kotlin DSL] 現在只允許一個 pluginManagement {} 區塊。

  • org.gradle.api.artifacts.cache.* 介面提供的快取控制 DSL 已不再可用。

  • getEnabledDirectoryReportDestinations()getEnabledFileReportDestinations()getEnabledReportNames() 都已從 org.gradle.api.reporting.ReportContainer 中移除。

  • StartParameter.projectPropertiesStartParameter.systemPropertiesArgs 現在會傳回不可變的映射。

從 4.5 及更早版本升級

已棄用

  • 您不應將註解處理器放在編譯類別路徑上,也不應使用 -processorpath 編譯器引數宣告它們。

    它們應該改為新增到 annotationProcessor 設定。如果您不想要進行任何處理,但您的編譯類別路徑不小心包含處理器(例如,作為您依賴的程式庫的一部分),請使用 -proc:none 編譯器引數來忽略它。

  • 請使用 CommandLineArgumentProvider 取代 CompilerArgumentProvider

潛在的重大變更

  • Java 外掛程式現在會為每個來源集新增 sourceSetAnnotationProcessor 設定,如果其中任何一個與您現有的設定相符,則可能會造成中斷。我們建議您移除衝突的設定宣告。

  • StartParameter.taskOutputCacheEnabled 屬性已被 StartParameter.setBuildCacheEnabled(boolean) 取代。

  • Visual Studio 整合現在僅為組建中的所有組件設定單一解決方案

  • Gradle 已將 HttpClient 4.4.1 取代為 4.5.5 版本。

  • Gradle 現在捆綁 kotlin-stdlib-jdk8 工件,而不是 kotlin-stdlib-jre8。這可能會影響您的組建。請參閱 Kotlin 文件以取得更多詳細資訊。

從 4.4 及更早版本升級

  • 請確保您有一個 settings.gradle 檔案:它可以避免效能上的損失,並讓您設定根專案的名稱。

  • Gradle 現在會忽略包含組建 (複合組建) 的組建快取設定,而是針對所有組建使用根組建的設定。

潛在的重大變更

  • 已移除兩個多載的 ValidateTaskProperties.setOutputFile() 方法。當從組建腳本存取任務時,它們會被自動產生的 setter 取代,但從外掛程式和組建腳本之外的其他程式碼存取時則不會。

  • Maven Publish 外掛程式現在會產生更完整的 maven-metadata.xml 檔案,包括維護 <snapshotVersion> 元素的列表。某些舊版本的 Maven 可能無法使用此中繼資料。

  • HttpBuildCache 不再遵循重新導向.

  • Depend 任務類型已被移除。

  • Project.file(Object) 不再針對不區分大小寫的檔案系統正規化檔案路徑的大小寫。它現在在這種情況下會忽略大小寫,並且不會觸碰檔案系統。

  • ListProperty 不再擴展 Property

從 4.3 及更早版本升級

潛在的重大變更

  • AbstractTestTask 現在由非 JVM 測試任務以及 Test 擴展。外掛程式應注意設定所有 AbstractTestTask 類型的任務,因為這個原因。

  • EclipseClasspath.defaultOutputDir 的預設輸出位置已從 $projectDir/bin 變更為 $projectDir/bin/default

  • 已移除已棄用的 InstallExecutable.setDestinationDir(Provider) — 請改用 InstallExecutable.installDirectory

  • 已移除已棄用的 InstallExecutable.setExecutable(Provider) — 請改用 InstallExecutable.executableFile

  • Gradle 將不再優先選擇在路徑中找到的 Visual Studio 版本,而不是其他位置。它現在是最後的選擇。

    您可以透過 VisualCpp.setInstallDir(Object) 指定您想要使用的 Visual Studio 版本的安裝目錄,來繞過工具鏈探索。

  • pluginManagement.repositories 現在是 RepositoryHandler 類型,而不是已移除的 PluginRepositoriesSpec

  • 相依性解析期間的 5xx HTTP 錯誤現在將在組建中觸發例外狀況。

  • 內嵌的 Apache Ant 已從 1.9.6 升級到 1.9.9。

  • Gradle 使用的幾個協力廠商程式庫已升級以修正安全性問題。

從 4.2 及更早版本升級

其他已棄用項目

潛在的重大變更

  • DefaultTask.newOutputDirectory() 現在會傳回 DirectoryProperty,而不是 DirectoryVar

  • DefaultTask.newOutputFile() 現在會傳回 RegularFileProperty,而不是 RegularFileVar

  • DefaultTask.newInputFile() 現在會傳回 RegularFileProperty,而不是 RegularFileVar

  • ProjectLayout.buildDirectory 現在會傳回 DirectoryProperty,而不是 DirectoryVar

  • AbstractNativeCompileTask.compilerArgs 現在是 ListProperty<String> 類型,而不是 List<String>

  • AbstractNativeCompileTask.objectFileDir 現在是 DirectoryProperty 類型,而不是 File

  • AbstractLinkTask.linkerArgs 現在是 ListProperty<String> 類型,而不是 List<String>

  • TaskDestroyables.getFiles() 不再是公開 API 的一部分。

  • 相依性的版本範圍重疊現在會導致 Gradle 選擇滿足所有宣告範圍的版本。

    例如,如果找到對 some-module 的相依性,其版本範圍為 [3,6],並且也間接地找到版本範圍為 [4,8] 的相依性,則 Gradle 現在會選擇版本 6 而不是 8。先前的行為是選擇 8。

  • 標記為 @OutputFiles@OutputDirectoriesIterable 屬性中元素的順序現在很重要。如果順序變更,則該屬性不再被視為是最新的。

    建議使用具有 @OutputFile/@OutputDirectory 註解的個別屬性,或改用具有 @OutputFiles/@OutputDirectoriesMap 屬性。

  • 當有另一個儲存庫可以檢查時,Gradle 將不再忽略來自儲存庫的相依性解析錯誤。相依性解析將會改為失敗。這會導致相對於解析結果更具決定性的行為。

從 4.1 及更早版本升級

潛在的重大變更

  • 已移除 TaskFilePropertyBuilderTaskOutputFilePropertyBuilder 上的 withPathSensitivity() 方法。

  • 捆綁的 bndlib 已從 3.2.0 升級到 3.4.0。

  • FindBugs 外掛程式不再呈現其分析的進度資訊。如果您以任何方式依賴該輸出,您可以使用 FindBugs.showProgress 啟用它。

從 4.0 升級

  • 請考慮使用新的 Worker API,讓您組建中的工作單元能夠平行執行。

已棄用的類別、方法和屬性

請遵循 API 連結以了解如何處理這些棄用(如果此處未提供額外資訊)

潛在的重大變更

  • 非 Java 專案對 Java 專案具有專案相依性,現在預設會使用 runtimeElements 設定,而不是 default 設定。

    若要覆寫此行為,您可以明確宣告要在專案相依性中使用的設定。例如:project(path: ':myJavaProject', configuration: 'default')

  • 預設 Zinc 編譯器從 0.3.13 升級到 0.3.15。

  • [Kotlin DSL] 基本套件名稱從 org.gradle.script.lang.kotlin 重新命名為 org.gradle.kotlin.dsl

詳細變更

[5.0] 預設記憶體設定已變更

命令列用戶端現在以 64MB 的堆積啟動,而不是 1GB。這可能會影響直接在用戶端 VM 內使用 --no-daemon 模式執行的組建。我們不鼓勵使用 --no-daemon,但如果您必須使用它,您可以使用 GRADLE_OPTS 環境變數來增加可用記憶體。

Gradle Daemon 現在以 512MB 的堆積啟動,而不是 1GB。大型專案可能必須使用 org.gradle.jvmargs 屬性來增加此設定。

所有 Worker(包括編譯器和測試執行器)現在都以 512MB 的堆積啟動。先前的預設值為實體記憶體的 1/4。大型專案可能必須在相關任務上增加此設定,例如 JavaCompileTest

[5.0] 程式碼品質外掛程式的新預設工具版本

以下程式碼品質外掛程式的預設工具版本已更新

[5.0] 程式庫升級

Gradle 使用的幾個程式庫已升級

  • Groovy 已從 2.4.15 升級到 2.5.4

  • Ant 已從 1.9.11 升級到 1.9.13

  • 用於存取 S3 後端 Maven/Ivy 儲存庫的 AWS SDK 已從 1.11.267 升級到 1.11.407

  • OSGi 外掛程式使用的 BND 程式庫已從 3.4.0 升級到 4.0.0

  • 用於存取 Google Cloud Storage 後端 Maven/Ivy 儲存庫的 Google Cloud Storage JSON API 用戶端程式庫已從 v1-rev116-1.23.0 升級到 v1-rev136-1.25.0。

  • Ivy 已從 2.2.0 升級到 2.3.0

  • Test 任務使用的 JUnit Platform 程式庫已從 1.0.3 升級到 1.3.1。

  • 用於存取 Maven 儲存庫的 Maven Wagon 程式庫已從 2.4 升級到 3.0.0。

  • SLF4J 已從 1.7.16 升級到 1.7.25

[5.0] 改善對相依性和版本約束的支援

在 Gradle 4.x 版本串流中,新的 @Incubating 功能已新增至相依性解析引擎。這些功能包括複雜的版本約束 (preferstrictlyreject)、相依性約束和 platform 相依性。

如果您一直在使用 IMPROVED_POM_SUPPORT 功能預覽,使用約束或 prefer、reject 和其他特定版本指示,請務必仔細查看您的相依性解析結果。

[5.0] BOM 匯入

Gradle 現在提供匯入物料清單 (BOM) 檔案的支援,這些檔案實際上是 POM 檔案,使用 <dependencyManagement> 區段來控制直接和間接相依性的版本。您只需要將 POM 宣告為 platform 相依性即可。

以下範例從宣告的 Spring Boot BOM 中選取 gsondom4j 相依性的版本

dependencies {
    // import a BOM
    implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE')

    // define dependencies without versions
    implementation 'com.google.code.gson:gson'
    implementation 'dom4j:dom4j'
}

[5.0] 使用 POM 時編譯和執行階段相依性的分離

自 Gradle 1.0 以來,執行階段範圍的相依性已包含在 Java 編譯類別路徑中,這有一些缺點

  • 編譯類別路徑比它需要的還要大得多,減慢了編譯速度。

  • 編譯類別路徑包含不影響編譯的執行階段範圍檔案,導致在這些檔案變更時不必要的重新編譯。

透過此新行為,Java 和 Java Library 外掛程式都遵循編譯和執行階段範圍的分離。這表示編譯類別路徑僅包含編譯範圍的相依性,而執行階段類別路徑也會新增執行階段範圍的相依性。如果您使用 Gradle 開發和發佈 Java 程式庫,其中 apiimplementation 相依性之間的分離反映在已發佈的範圍中,則這特別有用。

[5.0] DefaultTask 上屬性工廠方法的變更

DefaultTask 上的屬性工廠方法現在是 final

屬性工廠方法(例如 newInputFile())旨在從擴展 DefaultTask 的類型的建構函式中呼叫。這些方法現在是 final,以避免子類別覆寫這些方法並使用未初始化的狀態。

輸入和輸出不會自動註冊

這些方法傳回的 Property 實例不再自動註冊為任務的輸入或輸出。Property 實例需要在通常的方式中宣告為輸入或輸出,例如附加 @OutputFile 等註解或使用執行階段 API 註冊屬性。

例如,您之前可以使用以下語法,並讓 outputFile 實例同時註冊為宣告的輸出

build.gradle
class MyTask extends DefaultTask {
    // note: no annotation here
    final RegularFileProperty outputFile = newOutputFile()
}

task myOtherTask {
    def outputFile = newOutputFile()
    doLast { ... }
}
build.gradle.kts
open class MyTask : DefaultTask() {
    // note: no annotation here
    val outputFile: RegularFileProperty = newOutputFile()
}

task("myOtherTask") {
    val outputFile = newOutputFile()
    doLast { ... }
}

現在您必須明確註冊 outputFile,如下所示

build.gradle
class MyTask extends DefaultTask {
    @OutputFile // property needs an annotation
    final RegularFileProperty outputFile = project.objects.fileProperty()
}

task myOtherTask {
    def outputFile = project.objects.fileProperty()
    outputs.file(outputFile) // or to be registered using the runtime API
    doLast { ... }
}
build.gradle.kts
open class MyTask : DefaultTask() {
    @OutputFile // property needs an annotation
    val outputFile: RegularFileProperty = project.objects.fileProperty()
}

task("myOtherTask") {
    val outputFile = project.objects.fileProperty()
    outputs.file(outputFile) // or to be registered using the runtime API
    doLast { ... }
}

[5.0] Gradle 現在為 Java 9 及更高版本捆綁 JAXB

為了使用 S3 後端工件儲存庫,您先前必須在 Java 9 及更高版本上執行時,將 --add-modules java.xml.bind 新增至 org.gradle.jvmargs

由於 Java 11 不再包含 java.xml.bind 模組,Gradle 現在捆綁 JAXB 2.3.1 (com.sun.xml.bind:jaxb-impl) 並在 Java 9 及更高版本上使用它。

如果已設定,請從 org.gradle.jvmargs 中移除 --add-modules java.xml.bind 選項。

[5.0] gradlePluginPortal() 儲存庫預設不再尋找沒有 POM 的 JAR

使用此新行為,如果在外掛程式入口網站 (gradlePluginPortal()) 儲存庫中找到的外掛程式或外掛程式的間接相依性沒有 Maven POM,則解析將會失敗。

發佈到沒有 POM 的 Maven 儲存庫的工件應修正。如果您遇到此類工件,請要求外掛程式或程式庫作者發佈具有正確中繼資料的新版本。

如果您遇到不良外掛程式而無法解決,您可以重新啟用 JAR 作為 gradlePluginPortal() 儲存庫的中繼資料來源來解決問題

settings.gradle
pluginManagement {
    repositories {
        gradlePluginPortal().tap {
            metadataSources {
                mavenPom()
                artifact()
            }
        }
    }
}
settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal().apply {
            (this as MavenArtifactRepository).metadataSources {
                mavenPom()
                artifact()
            }
        }
    }
}

Java Library Distribution 外掛程式使用 Java Library 外掛程式

此外,由外掛程式建立的預設發佈將包含 runtimeClasspath 設定的所有工件,而不是已棄用的 runtime 設定。

組態避免 API 不允許常見的組態錯誤

組態避免 API 在 Gradle 4.9 中引入,可讓您避免建立和設定永遠不會使用的任務。

使用現有的 API,此範例新增了兩個任務 (foobar)

build.gradle
tasks.create("foo") {
    tasks.create("bar")
}
build.gradle.kts
tasks.create("foo") {
    tasks.create("bar")
}

當將其轉換為使用新的 API 時,會發生令人驚訝的事情:bar 不存在。新的 API 僅在必要時執行組態動作,因此任務 barregister() 僅在設定 foo 時執行。

build.gradle
tasks.register("foo") {
    tasks.register("bar") // WRONG
}
build.gradle.kts
tasks.register("foo") {
    tasks.register("bar") // WRONG
}

為了避免這種情況,Gradle 現在會偵測到這一點,並在使用新的 API 時,防止修改基礎容器(透過 create()register())。

[5.0] Worker API:Worker 的工作目錄不再可以設定

由於 JDK 11 不再支援變更執行中處理程序的工作目錄,因此現在禁止透過 Worker 的 fork 選項設定 Worker 的工作目錄。

所有 Worker 現在都使用相同的工作目錄以啟用重複使用。

請改為將檔案和目錄作為引數傳遞。

[4.10] 發佈到 AWS S3 需要新的權限

S3 儲存庫傳輸協定允許 Gradle 將工件發佈到 AWS S3 儲存貯體。從此版本開始,上傳到 S3 儲存貯體的每個工件都將配備 bucket-owner-full-control 標準 ACL。請確保用於發佈工件的 AWS 帳戶具有 s3:PutObjectAcls3:PutObjectVersionAcl 權限,否則上傳將會失敗。

{
    "Version":"2012-10-17",
    "Statement":[
        // ...
        {
            "Effect":"Allow",
            "Action":[
                "s3:PutObject", // necessary for uploading objects
                "s3:PutObjectAcl", // required starting with this release
                "s3:PutObjectVersionAcl" // if S3 bucket versioning is enabled
            ],
            "Resource":"arn:aws:s3:::myCompanyBucket/*"
        }
    ]
}

請參閱AWS S3 跨帳戶存取以取得更多資訊。

[4.9] 考慮嘗試用於任務建立和組態的延遲 API

Gradle 4.9 引入了一種新的方式來建立和設定以延遲方式運作的任務。當您對設定成本高昂的任務使用此方法,或者當您有非常多的任務時,如果這些任務沒有執行,您的組建組態時間可以顯著減少。

您可以在任務組態避免章節中瞭解更多關於延遲建立任務的資訊。您也可以在此部落格文章中閱讀關於此新功能的背景資訊。

[4.8] 切換到 Maven Publish 和 Ivy Publish 外掛程式

既然發佈外掛程式已穩定,我們建議您從標準 Java 專案(即基於 Java 外掛程式的專案)的舊版發佈機制移轉。這包括使用以下任何一個專案:Java Library 外掛程式Application 外掛程式War 外掛程式

若要使用新方法,只需將任何 upload<Conf> 設定取代為 publishing {} 區塊。請參閱發佈概觀章節以取得更多資訊。

[4.8] 使用延遲組態進行發佈外掛程式

在 Gradle 4.8 之前,publishing {} 區塊被隱式地視為在專案評估完成後執行其內部的所有邏輯。這令人困惑,因為它是唯一以這種方式運作的區塊。作為 Gradle 4.8 中的穩定化工作的一部分,我們正在棄用此行為,並要求所有使用者移轉其組建。

新的穩定行為可以透過將以下內容新增到您的設定檔來開啟

settings.gradle
enableFeaturePreview('STABLE_PUBLISHING')
settings.gradle.kts
enableFeaturePreview("STABLE_PUBLISHING")

我們建議使用本機儲存庫執行測試執行,以查看所有工件是否仍然具有預期的座標。在大多數情況下,一切都應該像以前一樣運作,您就完成了。但是,您的發佈區塊可能依賴於隱式延遲組態,尤其是當它依賴於在組建的組態階段可能會變更的值時。

例如,在新行為下,以下邏輯假設 jar.archiveBaseName 在設定 artifactId 之後不會變更

build.gradle
subprojects {
    publishing {
        publications {
            mavenJava {
                from components.java
                artifactId = jar.archiveBaseName
            }
        }
    }
}
build.gradle.kts
subprojects {
    publishing {
        publications {
            named<MavenPublication>("mavenJava") {
                from(components["java"])
                artifactId = tasks.jar.get().archiveBaseName.get()
            }
        }
    }
}

如果該假設不正確或未來可能不正確,則必須在 afterEvaluate {} 區塊內設定 artifactId,如下所示

build.gradle
subprojects {
    publishing {
        publications {
            mavenJava {
                from components.java
                afterEvaluate {
                    artifactId = jar.archiveBaseName
                }
            }
        }
    }
}
build.gradle.kts
subprojects {
    publishing {
        publications {
            named<MavenPublication>("mavenJava") {
                from(components["java"])
                afterEvaluate {
                    artifactId = tasks.jar.get().archiveBbaseName.get()
                }
            }
        }
    }
}

[4.8] 設定現有的 wrapperinit 任務

您不應再定義自己的 wrapperinit 任務。請改為設定現有的任務,例如透過轉換這個

build.gradle
task wrapper(type: Wrapper) {
    ...
}
build.gradle.kts
task<Wrapper>("wrapper") {
    ...
}

變成這個

build.gradle
wrapper {
    ...
}
build.gradle.kts
tasks.wrapper {
    ...
}

[4.8] Gradle 現在會遵循 Maven POM 排除項目中隱含的萬用字元

如果 Maven POM 中的排除項目缺少 groupIdartifactId,Gradle 過去會忽略該排除項目。現在,缺少的元素被視為隱含的萬用字元 — 例如 <groupId>*</groupId> — 這表示您的某些相依性現在可能會被排除,而以前則不會。

您將需要明確宣告您需要的任何遺失的相依性。

[4.7] Gradle 純文字主控台輸出的結構變更

純文字主控台模式現在以與豐富主控台一致的方式格式化輸出,這表示輸出格式已變更。例如

  • 給定任務產生的輸出現在會分組在一起,即使其他任務與它並行執行。

  • 任務執行標頭以 "> Task" 字首列印。

  • 在組建執行期間產生的所有輸出都會寫入標準輸出檔案句柄。這包括寫入 System.err 的訊息,除非您將標準錯誤重新導向到檔案或任何其他非主控台目的地。

這可能會破壞從純文字主控台輸出中抓取詳細資訊的工具。

[4.6] 與編譯、連結和安裝相關的原生任務 API 變更

許多與編譯、連結和安裝原生程式庫和應用程式相關的任務已轉換為 Provider API,以便它們支援延遲組態。此轉換為任務的 API 引入了一些重大變更,使其符合 Provider API 的慣例。

以下任務已變更

AbstractLinkTask 及其子類別
  • getDestinationDir() 已被 getDestinationDirectory() 取代。

  • getBinaryFile()getOutputFile() 已被 getLinkedFile() 取代。

  • setOutputFile(File) 已移除。請改用 Property.set()

  • setOutputFile(Provider) 已移除。請改用 Property.set()

  • getTargetPlatform() 已變更為傳回 Property

  • setTargetPlatform(NativePlatform) 已移除。請改用 Property.set()

  • getToolChain() 已變更為傳回 Property

  • setToolChain(NativeToolChain) 已移除。請改用 Property.set()

CreateStaticLibrary
  • getOutputFile() 已變更為傳回 Property

  • setOutputFile(File) 已移除。請改用 Property.set()

  • setOutputFile(Provider) 已移除。請改用 Property.set()

  • getTargetPlatform() 已變更為傳回 Property

  • setTargetPlatform(NativePlatform) 已移除。請改用 Property.set()

  • getToolChain() 已變更為傳回 Property

  • setToolChain(NativeToolChain) 已移除。請改用 Property.set()

  • getStaticLibArgs() 已變更為傳回 ListProperty

  • setStaticLibArgs(List) 已移除。請改用 ListProperty.set()

InstallExecutable
  • getSourceFile() 已被 getExecutableFile() 取代。

  • getPlatform() 已被 getTargetPlatform() 取代。

  • setTargetPlatform(NativePlatform) 已移除。請改用 Property.set()

  • getToolChain() 已變更為傳回 Property

  • setToolChain(NativeToolChain) 已移除。請改用 Property.set()

以下項目也看到了類似的變更

[4.6] Visual Studio 整合僅支援組建的所有組件的單一解決方案檔案

VisualStudioExtension 不再具有 solutions 屬性。相反地,您可以在根專案中使用 VisualStudioRootExtension 設定單一解決方案,如下所示

build.gradle
model {
    visualStudio {
        solution {
            solutionFile.location = "vs/${name}.sln"
        }
    }
}

此外,不再有為每個組件產生解決方案檔案的個別任務,而是單一的 visualStudio 任務,它會產生一個涵蓋組建中所有組件的解決方案檔案。

[4.5] HttpBuildCache 不再遵循重新導向

當透過 HttpBuildCache 連接到 HTTP 組建快取後端時,Gradle 不再遵循重新導向,而是將它們視為錯誤。從組建快取後端取得重新導向主要是組態錯誤 — 例如,使用 "http" URL 而不是 "https" — 並且對效能有負面影響。

[4.4] 協力廠商相依性升級

此版本包含幾個協力廠商相依性的升級

  • jackson: 2.6.6 → 2.8.9

  • plexus-utils: 2.0.6 → 2.1

  • xercesImpl: 2.9.1 → 2.11.0

  • bsh: 2.0b4 → 2.0b6

  • bouncycastle: 1.57 → 1.58

這修正了以下安全性問題

Gradle 沒有公開這些協力廠商相依性的公開 API,但那些自訂 Gradle 的人會希望知道這一點。