目錄
從Apache Maven遷移構建
💡患有緩慢的Maven構建? 在此處註冊以參加我們的構建緩存培訓課程,以瞭解Gradle Enterprise如何將Maven構建速度提高多達90%。
Apache Maven是用於Java和其他基於JVM的項目的構建工具,這些項目已被廣泛使用,因此想要使用Gradle的人們經常不得不遷移現有的Maven構建。本指南將通過解釋這兩種工具的模型之間的差異和相似之處,並提供簡化步驟可以幫助您進行遷移。
轉換構建可能會很嚇人,但您不必一個人做。您可以從help.gradle.org搜索文檔,論壇和StackOverflow,或者在遇到麻煩時訪問Gradle社區。
進行遷移
Gradle和Maven之間的主要區別是靈活性,性能,用戶體驗和依賴性管理。Maven與Gradle功能比較中提供了這些方面的直觀概述。
從Gradle 3.0開始,Gradle投入了大量資金,以使Gradle的構建速度更快,並具有諸如構建緩存,避免編譯和改進的增量Java編譯器等功能。對於大多數項目,即使不使用構建緩存,Gradle的速度也比Maven快2-10倍。可以在此處找到有關從Maven切換到Gradle的深入性能比較和業務案例。
一般準則
對於如何構建項目,Gradle和Maven有着根本不同的看法。Gradle提供了一種靈活且可擴展的構建模型,該模型將實際工作委託給任務依賴關係圖。Maven使用固定的線性階段模型,可以在其中附加目標(完成工作的事物)。這可能會使兩者之間的遷移看起來令人生畏,但遷移可能出奇的容易,因爲Gradle遵循許多與Maven相同的約定(例如標準項目結構) ,並且其依賴項管理以類似的方式工作。
在這裏,我們列出了一系列步驟供您遵循,這將有助於促進將任何Maven構建移植到Gradle:
💡並排保留舊的Maven構建和新的Gradle構建。您知道Maven構建可以工作,因此您應該保留它,直到您確信Gradle構建可以生成所有相同的工件,然後再做您需要的事情。這也意味着用戶可以在不獲取源樹的新副本的情況下嘗試Gradle構建。
-
構建掃描將使可視化您現有Maven構建中發生的事情變得更加容易。對於Maven構建,您將能夠查看項目結構,正在使用的插件,構建步驟的時間表等等。保持方便,以便可以將其與轉換項目時獲得的Gradle構建掃描進行比較。
-
開發一種機制來驗證兩個構建產生相同的工件
這是確保您的部署和測試不中斷的至關重要的一步。即使是很小的更改,例如JAR中清單文件的內容,也會引起問題。如果您的Gradle構建生成的輸出與Maven構建生成的輸出相同,則這將使您和其他人對切換充滿信心,並使更容易實施將帶來最大收益的重大更改。
這並不意味着您需要在每個階段都驗證每個工件,儘管這樣做可以幫助您快速確定問題的根源。您可以只關注關鍵輸出,例如最終報告以及已發佈或部署的工件。
與Maven相比,您需要考慮Gradle產生的構建輸出中的某些固有差異。生成的POM將僅包含消耗所需的信息,並且它們將針對該場景正確使用
<compile>
和確定<runtime>
範圍。您可能還會看到歸檔文件中的文件順序和類路徑中的文件順序不同。大多數差異將是良性的,但值得識別它們並驗證它們是否正確。 -
這將創建您需要的所有Gradle構建文件,即使對於多模塊構建也是如此。對於更簡單的Maven項目,Gradle構建將可以運行!
-
構建掃描將使可視化構建中的事情變得更加容易。對於Gradle構建,您將能夠查看項目結構,依賴關係(常規和項目間的依賴關係),正在使用的插件以及構建的控制檯輸出。
此時您的構建可能會失敗,但這沒關係;掃描仍將運行。將Gradle構建的構建掃描與Maven構建的構建掃描進行比較,然後繼續執行此列表以排除故障。
我們建議您在遷移期間定期生成構建掃描,以幫助您確定問題並排除故障。如果需要,您還可以使用Gradle構建掃描來確定提高構建性能的機會,畢竟,性能首先是切換到Gradle的主要原因。
-
通過配置額外的源集,可以簡單地遷移許多測試。如果您使用的是第三方庫(例如FitNesse),請查看Gradle Plugin Portal上是否有合適的社區插件。
-
用Gradle等效項替換Maven插件
對於流行的插件,Gradle經常有一個等效的插件供您使用。您可能還會發現可以用內置的Gradle功能替換插件。作爲最後的選擇,您可能需要通過自己的自定義插件和任務類型重新實現Maven插件。
本章的其餘部分更詳細地介紹了將構建從Maven遷移到Gradle的特定方面。
瞭解構建生命週期
Maven構建基於構建生命週期的概念,該概念由一組固定階段組成。這可能會成爲用戶遷移到Gradle的障礙,因爲它的構建生命週期有所不同,儘管瞭解Gradle的構建方式如何適合初始化,配置和執行階段的結構很重要。幸運的是,Gradle的功能可以模仿Maven的各個階段:生命週期任務。
這些使您可以通過創建僅依賴於您感興趣的任務的無操作任務來定義自己的“生命週期”。並且爲了使Maven用戶更輕鬆地過渡到Gradle,Base插件 -由所有JVM語言應用Java庫插件之類的插件 —提供了一組與主要Maven階段相對應的生命週期任務。
這是一些主要的Maven階段以及它們映射到的Gradle任務的列表:
clean
使用clean
基本插件提供的任務。
compile
使用Java插件和其他JVM語言插件classes
提供的任務。這將編譯所有語言的所有源文件的所有類,並通過processResources任務執行資源過濾。
test
使用Java插件提供的test
任務。它僅運行單元測試,或更具體地說,運行組成test
源集的測試。
package
使用基本插件提供的assemble
任務。這將構建適合項目的任何軟件包,例如Java庫的JAR或傳統Java Webapp的WAR。
verify
使用基本插件提供的check
任務。這將運行附加到它的所有驗證任務,通常包括單元測試,任何靜態分析任務(例如Checkstyle)以及其他任務。如果要包括集成測試,則必須手動配置這些,這是一個簡單的過程。x
install
使用Maven發佈插件提供的publishToMavenLocal
任務。
Gradle還允許您解析對本地Maven緩存的依賴關係,如“聲明存儲庫”部分中所述。
deploy
使用Maven Publish插件提供的publish
任務 - 如果您的構建正在使用該Maven插件,請確保選擇舊的Maven插件(ID: maven
)。這會將您的程序包發佈到所有已配置的發佈存儲庫。即使定義了多個存儲庫,也有其他任務可以使您發佈到單個存儲庫。
請注意,默認情況下,Maven Publish Plugin不發佈source 和 Javadoc JARs ,但是可以按照構建Java項目的指南中的說明輕鬆激活它。
執行自動轉換
Gradle的init
任務通常用於創建新的骨架項目,但是您也可以使用它將現有的Maven構建自動轉換爲Gradle。將Gradle安裝到系統上後,只需執行以下命令
> gradle init
從根項目目錄中,讓Gradle做它的事情。這基本上包括解析現有的POM並生成相應的Gradle構建腳本。如果您要遷移多項目版本, Gradle還將創建一個設置腳本。
您會發現新的Gradle構建包括以下內容:
-
POM中指定的所有自定義存儲庫
-
您的外部和項目間依賴性
-
用於構建項目的適當插件(僅限於Maven Publish,Java和War插件中的一個或多個)
有關自動轉換功能的完整列表,請參見Build Init插件一章。
要記住的一件事是程序集不會自動轉換。它們不一定要轉換,但是您將需要做一些手工工作。選項包括:
-
使用分發插件
-
使用應用程序插件
-
從Gradle插件門戶使用合適的社區插件
如果您的Maven構建沒有很多插件或以自定義方式提供很多插件,則只需運行
> gradle build
遷移完成後。這將運行測試併產生所需的工件,而您無需任何額外的干預。
遷移依賴項
Gradle的依賴項管理系統比Maven的依賴項管理系統更靈活,但它仍支持相同的存儲庫,聲明的依賴項,範圍(Gradle中的依賴項配置)和可傳遞依賴項的概念。實際上,Gradle與兼容Maven的存儲庫完美配合,這使得遷移依賴關係變得容易。
✨兩種工具之間的顯着區別是它們如何管理版本衝突。Maven使用“最接近”的匹配算法,而Gradle選擇最新的匹配算法。不過,請放心,您可以控制選擇哪個版本,如管理傳遞依賴項中所述。
在以下各節中,我們將向您展示如何遷移Maven構建的依賴管理信息中最常見的元素。
聲明依賴
Gradle使用與Maven相同的依賴項標識符組件:group ID, artifact ID ,version。它還支持分類器。因此,您需要做的就是將標識符的依賴項信息替換爲Gradle的語法,這在“聲明依賴項”一章中進行了介紹。
例如,考慮對Log4J的這種Maven風格的依賴關係:
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
在Gradle構建腳本中,這種依賴關係如下所示:
例子1.聲明一個簡單的編譯時依賴
Groovy
build.gradle
dependencies {
implementation 'log4j:log4j:1.2.12' // (1)
}
Kotlin
build.gradle.kts
dependencies {
implementation("log4j:log4j:1.2.12") // (1)
}
1.將Log4J的1.2.12版附加到implementation
配置(作用域)
字符串標識符采用的Maven的值groupId
,artifactId,
version
,雖然Gradle指它們作爲group
,module
和version
。
上面的示例提出了一個明顯的問題:該implementation
配置是什麼?它是Java插件提供的標準依賴項配置之一,通常被用來替代Maven的默認compile
範圍。
Maven的作用域和Gradle的標準配置之間的幾個區別歸結爲Gradle區分了構建模塊所需的依賴項和構建依賴於該模塊的模塊所需的依賴項。Maven沒有這種區別,因此已發佈的POM通常包括庫的使用者實際上不需要的依賴項。
以下是主要的Maven依賴範圍以及如何處理它們的遷移:
compile
Gradle有兩種配置可以代替compile
範圍使用:implementation
和api
。 前者適用於所有應用Java插件的項目,而api
僅適用於專門應用Java庫插件的項目。
在大多數情況下,您應該只使用implementation
配置,尤其是在構建應用程序或webapp時。 但是如果您要構建庫,則可以在構建Java庫的部分中瞭解使用api
聲明哪些依賴項。 上面鏈接的Java庫插件一章提供了有關api
和implementation
之間區別的更多信息。
runtime
使用runtimeOnly
配置。
test
Gradle區分了compile 項目測試所需的那些依賴項和僅運行它們所需的那些依賴項。
應針對testImplementation
配置聲明測試編譯所需的依賴關係。僅運行測試所需的那些應該使用testRuntimeOnly
。
provided
使用compileOnly
配置。
請注意,War Plugin添加providedCompile
和providedRuntime
依賴項配置。它們的行爲compileOnly
與WAR文件中的行爲略有不同,並且僅確保這些依賴項未打包。但是,依賴項包含在運行時和測試運行時類路徑中,因此如果您需要這種行爲,請使用這些配置。
import
該import
範圍主要在<dependencyManagement>
塊內使用,並且僅適用於僅POM的出版物。閱讀有關使用物料清單的部分,以瞭解有關如何複製此行爲的更多信息。
您還可以指定對僅POM的發佈的常規依賴性。在這種情況下,在該POM中聲明的依賴關係將被視爲構建的常規傳遞依賴關係。
例如,假設您要使用 groovy-all
POM進行測試。這是僅POM的出版物,在<dependencies>
塊內列出了自己的依賴性。Gradle構建中的適當配置如下所示:
示例2.Consuming a POM-only依賴項
Groovy
build.gradle
dependencies {
testImplementation 'org.codehaus.groovy:groovy-all:2.5.4'
}
Kotlin
build.gradle.kts
dependencies {
testImplementation("org.codehaus.groovy:groovy-all:2.5.4")
}
這樣的結果將是將POM 中的所有compile
和runtime
範圍依賴項groovy-all
添加到測試運行時類路徑,而僅將compile
範圍依賴項添加到測試編譯類路徑。與其他作用域的依賴關係將被忽略。
聲明存儲庫
Gradle允許您從任何與Maven兼容或與Ivy兼容的存儲庫中檢索已聲明的依賴項。與Maven不同,它沒有默認存儲庫,因此您必須聲明至少一個。爲了具有與Maven構建相同的行爲,只需在Gradle構建中配置Maven Central,如下所示:
示例3.將構建配置爲使用Maven Central
Groovy
build.gradle
repositories {
mavenCentral()
}
Kotlin
build.gradle.kts
repositories {
mavenCentral()
}
您還可以使用該repositories {}
塊來配置自定義存儲庫,如“存儲庫類型”一章中所述。
最後,Gradle允許您解決對local Maven cache/repository依賴關係。這有助於Gradle構建與Maven構建進行互操作,但是如果您不需要這種互操作性,則不應使用該技術。如果要通過文件系統共享已發佈的工件,請考慮使用 file://
URL 配置自定義Maven存儲庫。
您可能還對了解Gradle自己的依賴項緩存感興趣,後者比Maven的行爲更可靠,並且可以被多個併發的Gradle進程安全地使用。
控制依賴項版本
傳遞依賴項的存在意味着您可以輕鬆地在依賴關係圖中最終獲得同一依賴項的多個版本。默認情況下,Gradle將選擇圖中的依賴項的最新版本,但這並不總是正確的解決方案。這就是爲什麼它提供了幾種機制來控制解決給定依賴項的哪個版本的原因。
在每個項目的基礎上,您可以使用:
在控制傳遞依賴項一章中列出了更多專門的選項。
如果要確保多項目構建中所有項目的版本一致性,類似於<dependencyManagement>
Maven中的塊的工作方式,則可以使用Java Platform Plugin。這使您可以聲明一組可以應用於多個項目的依賴關係約束。您甚至可以將平臺發佈爲Maven BOM或使用Gradle的元數據格式發佈。有關如何執行此操作的更多信息,請參見插件頁面,尤其是在使用平臺部分,以瞭解如何將平臺應用於同一構建中的其他項目。
排除傳遞依賴
Maven構建使用排除項將不需要的依賴關係或不需要的依賴關係版本排除在依賴關係圖中。您可以使用Gradle做同樣的事情,但這不一定是正確的事情。Gradle提供了其他選項,這些選項可能更適合給定的情況,因此您確實需要了解爲什麼存在排除項才能正確遷移它。
如果您出於與版本無關的原因而要排除依賴項,請查看dependency_downgrade_and_exclude.html的部分。它顯示瞭如何將排除項附加到整個配置(通常是最合適的解決方案)或依賴項。您甚至可以輕鬆地將排除應用於所有配置。
如果您對控制實際解決依賴關係的版本更感興趣,請參閱上一節。
處理可選的依賴
關於可選依賴項,您可能會遇到兩種情況:
-
您的某些傳遞依賴項被聲明爲可選
-
您想在項目的已發佈POM中將某些直接依賴項聲明爲可選
對於第一種情況,Gradle的行爲與Maven相同,只是忽略了聲明爲可選的任何傳遞依賴。如果相同的依存關係在依存關係圖中的其他位置顯示爲非可選,則無法解析它們並且對所選版本沒有影響。
至於將依賴項發佈爲可選的,Gradle提供了一個更豐富的模型,稱爲Feature Variants,它可以讓您聲明庫提供的“可選功能”。
使用物料清單(BOM)
Maven允許您通過在<dependencyManagement>
打包類型爲的POM文件的一部分內定義依賴項來共享依賴項約束pom
。然後可以將這種特殊類型的POM(物料清單)導入其他POM中,以便在項目中擁有一致的庫版本。
Gradle可以通過基於 platform() 和 enforcedPlatform() 方法的特殊依賴項語法,將此類BOM用於相同的目的。您只需以常規方式聲明依賴項,然後將依賴項標識符包裝在適當的方法中,如“imports” Spring Boot Dependencies BOM 的示例所示:
例子4.在Gradle版本中導入BOM
Groovy
build.gradle
dependencies {
implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE') // (1)
implementation 'com.google.code.gson:gson' // (2)
implementation 'dom4j:dom4j'
}
Kotlin
build.gradle.kts
dependencies {
implementation(platform("org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE")) // (1)
implementation("com.google.code.gson:gson") // (2)
implementation("dom4j:dom4j")
}
-
應用Spring Boot Dependencies BOM
-
添加依賴項,其版本由該BOM表定義
您可以瞭解更多關於此功能之間的差異platform()
,並enforcedPlatform()
在上一節importing version recommendations from a Maven BOM。
✨您可以使用此功能將
<dependencyManagement>
來自任何依賴項的POM 的信息應用於Gradle構建,即使那些沒有打包類型爲的信息也是如此pom
。雙方platform()
並enforcedPlatform()
會忽略聲明的依賴<dependencies>
塊。
遷移多模塊構建(項目聚合)
Maven的多模塊構建與Gradle的多項目構建很好地映射。嘗試相應的教程,以瞭解如何設置基本的多項目Gradle構建。
要遷移多模塊Maven構建,只需執行以下步驟:
1.創建一個與根POM塊匹配的<modules>
設置腳本。
例如,以下代碼<modules>
塊:
<modules>
<module>simple-weather</module>
<module>simple-webapp</module>
</modules>
可以通過在設置腳本中添加以下行來遷移:
例子5.聲明哪些項目是構建的一部分
Groovy
build.gradle
rootProject.name = 'simple-multi-module' // (1)
include 'simple-weather', 'simple-webapp' // (2)
Kotlin
build.gradle.kts
rootProject.name = "simple-multi-module" // (1)
include("simple-weather", "simple-webapp") // (2)
-
設置整個項目的名稱
-
配置兩個子項目作爲此構建的一部分
Output of gradle projects
> gradle projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'simple-multi-module'
+--- Project ':simple-weather'
\--- Project ':simple-webapp'
To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :simple-weather:tasks
2.將跨模塊依賴項替換爲項目依賴項。
3.使用跨項目配置複製項目繼承。
這基本上涉及創建一個根項目構建腳本,該腳本將共享配置注入到適當的子項目中。
跨項目共享版本
如果要複製在根POM文件的dependencyManagement
部分中聲明的具有依賴項版本的Maven模式,最好的方法是利用java-platform
插件。您將需要爲此添加一個專用項目,並在構建的常規項目中使用它。有關此模式的更多詳細信息,請參見文檔。
遷移Maven配置文件和屬性
Maven允許您使用各種屬性對構建進行參數化。一些是項目模型的只讀屬性,其他是在POM中用戶定義的。它甚至允許您將系統屬性視爲項目屬性。
Gradle具有類似的項目屬性系統,儘管它可以區分項目屬性和系統屬性。例如,您可以在以下位置定義屬性:
-
the build script
-
a
gradle.properties
file in the root project directory -
a
gradle.properties
file in the$HOME/.gradle
directory
這些不是唯一的選擇,因此,如果您有興趣瞭解有關如何以及在何處定義屬性的更多信息,請查閱“構建環境”一章。
您需要了解的一項重要行爲是,在構建腳本和一個外部屬性文件中定義了相同的屬性時會發生什麼:構建腳本值優先。總是。幸運的是,您可以模仿配置文件的概念以提供可覆蓋的默認值。
這使我們進入了Maven配置文件。這些是根據環境,目標平臺或任何其他類似因素啓用和禁用不同配置的方法。從邏輯上講,它們僅是有限的“ if”語句。並且由於Gradle具有更強大的聲明條件的方法,因此它不需要對配置文件的正式支持(依賴項的POM中除外)。您將看到,通過將條件與輔助構建腳本結合起來,可以輕鬆獲得相同的行爲。
假設您有不同的部署設置,具體取決於環境:本地開發(默認),測試環境和生產。要添加型材式的行爲,首先在項目的根每個環境中創建構建腳本:profile-default.gradle
,profile-test.gradle
,和profile-prod.gradle
。然後,您可以根據自己選擇的項目屬性有條件地應用這些概要文件腳本之一。
下面的示例演示了使用名爲的項目屬性buildProfile
和配置文件腳本的基本技術,該腳本簡單地初始化了名爲的額外項目屬性message
:
例子6.模仿Gradle中的Maven配置文件的行爲
Groovy
build.gradle
if (!hasProperty('buildProfile')) ext.buildProfile = 'default' // (1)
apply from: "profile-${buildProfile}.gradle" // (2)
task greeting {
doLast {
println message // (3)
}
}
profile-default.gradle
ext.message = 'foobar' // (4)
profile-test.gradle
ext.message = 'testing 1 2 3' // (4)
profile-prod.gradle
ext.message = 'Hello, world!' // (4)
Kotlin
build.gradle.kts
val buildProfile: String? by project // (1)
apply(from = "profile-${buildProfile ?: "default"}.gradle.kts") // (2)
tasks.register("greeting") {
val message: String by project.extra
doLast {
println(message) // (3)
}
}
profile-default.gradle.kts
val message by extra("foobar") // (4)
profile-test.gradle.kts
val message by extra("testing 1 2 3") // (4)
profile-prod.gradle.kts
val message by extra("Hello, world!") // (4)
-
檢查(Groovy)是否存在或綁定(Kotlin)
buildProfile
項目屬性 -
使用
buildProfile
腳本文件名中的值應用適當的配置文件腳本 -
打印出
message
額外項目屬性的值 -
初始化
message
額外的項目屬性,然後可以在主構建腳本中使用其值
Output of gradle greeting
> gradle greeting
foobar
Output of gradle -PbuildProfile=test greeting
> gradle -PbuildProfile=test greeting
testing 1 2 3
您不僅限於檢查項目屬性。您還可以檢查環境變量,JDK版本,運行內部版本的OS或您可以想象的任何其他內容。
要記住的一件事是,高級條件語句使構建更難以理解和維護,類似於它們使面向對象的代碼複雜化的方式。配置文件也是如此。Gradle提供了許多更好的方法來避免廣泛使用Maven經常需要的配置文件,例如,通過配置彼此不同的多個任務。請參見Maven發佈插件創建的publishPubNamePublicationToRepoNameRepository
任務。
有關在Gradle中使用Maven概要文件的冗長討論,請參閱此博客文章。
篩選資源
Maven有一個稱爲的階段,默認情況下process-resources
目標已resources:resources
綁定到該階段。這爲構建作者提供了對各種文件(例如Web資源,打包的屬性文件等)執行變量替換的機會。
Gradle的Java插件提供了processResources
執行相同操作的任務。這是一個複製任務,src/main/resources
默認情況下將文件從配置的資源目錄複製 到輸出目錄。與任何Copy
任務一樣,您可以對其進行配置以執行文件過濾,重命名和內容過濾。
例如,以下配置將源文件視爲Groovy SimpleTemplateEngine
模板,version
並buildNumber
爲這些模板提供屬性:
例子7.通過processResources
任務過濾資源的內容
Groovy
build.gradle
processResources {
expand(version: version, buildNumber: currentBuildNumber)
}
Kotlin
build.gradle.kts
tasks {
processResources {
expand("version" to version, "buildNumber" to currentBuildNumber)
}
}
請參閱CopySpec的API文檔以查看所有可用選項。
配置集成測試
許多Maven的建立某種形式的一體化集成測試,它的Maven通過一組額外的階段的支持:pre-integration-test
,integration-test
,post-integration-test
,和verify
。它還使用Failsafe插件代替Surefire,以便失敗的集成測試不會自動使構建失敗(因爲您可能需要清理資源,例如正在運行的應用程序服務器)。
如我們在Testing in Java & JVM projects章節中所述,此行爲很容易在帶有源集的Gradle中複製。然後,您可以使用Task.finalizedBy()將清理任務(例如關閉測試服務器的清理任務)配置爲始終在集成測試之後運行,而不管它們是否成功。
如果您確實不希望集成測試使構建失敗,那麼可以使用Java測試一章的“測試執行“部分中描述的Test.ignoreFailures設置。
源集還爲您在集成測試中放置源文件的位置提供了很大的靈活性。您可以輕鬆地將它們保存在與單元測試相同的目錄中,或更可取的是,保存在單獨的源目錄中,例如src/integTest/java
。要支持其他類型的測試,您只需添加更多源集和測試任務!
遷移常用插件
Maven和Gradle共享一種通過插件擴展構建的通用方法。儘管表面上的插件系統有很大不同,但是它們共享許多基於功能的插件,例如:
-
Shade/Shadow
-
Jetty
-
Checkstyle
-
JaCoCo
-
AntRun (請參閱下一節)
爲什麼這麼重要?因爲許多插件依賴於標準Java約定,所以遷移僅是在Gradle中複製Maven插件的配置即可。例如,這是一個簡單的Maven Checkstyle插件配置:
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
...
遷移到Gradle時,可以安全地忽略配置塊之外的所有內容。在這種情況下,相應的Gradle配置如下所示:
例子8.配置Gradle Checkstyle插件
Groovy
build.gradle
checkstyle {
config = resources.text.fromFile('checkstyle.xml', 'UTF-8')
showViolations = true
ignoreFailures = false
}
Kotlin
build.gradle.kts
checkstyle {
config = resources.text.fromFile("checkstyle.xml", "UTF-8")
isShowViolations = true
isIgnoreFailures = false
}
Checkstyle任務會自動添加爲check
任務的依賴項,其中還包括test
。如果要確保Checkstyle在測試之前運行,則只需使用mustRunAfter()方法指定一個順序即可:
例子9.控制checkstyle
任務何時運行
Groovy
build.gradle
test.mustRunAfter checkstyleMain, checkstyleTest
Kotlin
build.gradle.kts
tasks {
test {
mustRunAfter(checkstyleMain, checkstyleTest)
}
}
如您所見,Gradle配置通常比Maven等效配置短得多。您還將擁有一個更加靈活的執行模型,因爲您不再受Maven固定階段的約束。
從Maven遷移項目時,請不要忘記源集。與Maven相比,它們通常爲處理集成測試或生成的源提供了更優雅的解決方案,因此您應將它們納入遷移計劃中。
Ant目標
許多Maven構建依賴於AntRun插件來自定義構建,而沒有實現自定義Maven插件的開銷。Gradle沒有等效的插件,因爲Ant通過該ant
對象是Gradle構建中的一等公民。例如,您可以使用Ant的Echo任務,如下所示:
例子10.調用Ant任務
Groovy
build.gradle
task sayHello {
doLast {
ant.echo message: 'Hello!'
}
}
Kotlin
build.gradle.kts
tasks.register("sayHello") {
doLast {
ant.withGroovyBuilder {
"echo"("message" to "Hello!")
}
}
}
本機還支持Ant屬性和文件集。要了解更多信息,請參閱《從Gradle中使用Ant》。
💡僅創建自定義任務類型來替換Ant爲您所做的工作可能更簡單,更簡潔。然後,您可以更輕鬆地從增量構建和其他有用的Gradle功能中受益。
瞭解您不需要哪些插件
值得記住的是,Gradle版本通常比Maven版本更易於擴展和自定義。在這種情況下,這意味着您可能不需要Gradle插件來替換Maven。例如,Maven Enforcer插件允許您控制依賴項版本和環境因素,但是可以在常規Gradle構建腳本中輕鬆配置這些內容。
處理不常見和自定義的插件
您可能會遇到在Gradle中沒有對應版本的Maven插件,尤其是當您或組織中的某人編寫了自定義插件時。這種情況取決於您瞭解Gradle(以及可能的Maven)的工作方式,因爲您通常必須編寫自己的插件。
爲了進行遷移,Maven插件有兩種主要類型:
-
Those that use the Maven project object.
-
Those that don’t.
爲什麼這很重要?因爲如果使用後者之一,則可以輕鬆地將其重新實現爲自定義Gradle任務類型。只需定義與mojo參數相對應的任務輸入和輸出,然後將執行邏輯轉換爲任務動作即可。
如果插件依賴於Maven項目,那麼您將不得不重寫它。不要首先考慮Maven插件的工作原理,而要看看它試圖解決的問題。然後嘗試解決如何在Gradle中解決該問題。您可能會發現這兩個構建模型之間的差異足以使Maven插件代碼“轉錄”到Gradle插件中才有效。從好的方面來說,該插件可能比原始的Maven插件更容易編寫,因爲Gradle具有更豐富的構建模型和API。
如果您確實需要通過構建腳本或插件來實現自定義邏輯,請查看與插件開發相關的指南。另外,請務必熟悉Gradle的 Groovy DSL Reference,該參考提供了有關您將使用的API的全面文檔。它詳細介紹了標準配置塊(以及支持他們的對象),系統(核心類型Project
,Task
等等),和一組標準的任務類型。主要入口點是Project接口,因爲它是支持構建腳本的頂級對象。
進一步閱讀
本章涵蓋了將Maven構建遷移到Gradle的主要主題。剩下的就是遷移期間或遷移之後可能有用的其他一些方面:
-
瞭解如何配置Gradle的構建環境,包括用於運行Gradle的JVM設置
-
瞭解如何有效構建構建
-
配置Gradle的日誌並在構建中使用
最後,本指南僅涉及Gradle的一些功能,我們鼓勵您從用戶手冊的其他章節以及教程式的Gradle Guides中瞭解其餘內容。