從 Apache Maven 遷移建置
Apache Maven 是一個用於 Java 和其他基於 JVM 的專案的建置工具。將現有的 Maven 建置遷移到 Gradle 是很常見的。
本指南將透過說明這兩個工具之間的差異和相似之處,並提供可遵循的步驟來簡化流程,協助進行此類遷移。
提出遷移理由
Gradle 和 Maven 之間的主要差異在於靈活性、效能、使用者體驗和相依性管理。
這些面向的視覺化概觀可在 Maven vs Gradle 功能比較 中取得。
一般準則
Gradle 和 Maven 對於如何建置專案有根本上不同的看法。Gradle 提供一個彈性且可延伸的建置模型,將實際工作委派給執行任務圖形。Maven 使用固定線性階段模型,您可以將目標(執行工作的項目)附加到該模型。這可能會讓在兩者之間進行移轉看起來令人望而生畏,但移轉可能會出乎意料地容易,因為 Gradle 遵循許多與 Maven 相同的慣例,例如 標準專案結構,而且其相依性管理運作方式類似。
在此,我們列出一系列步驟供您遵循,有助於促進任何 Maven 建置移轉至 Gradle
並排保留舊的 Maven 建置和新的 Gradle 建置。您知道 Maven 建置有效,因此您應該保留它,直到您確信 Gradle 建置產生所有相同的成品。這也表示使用者可以在不建立原始碼樹的新副本的情況下嘗試 Gradle 建置。 |
-
建置掃描將讓您更容易視覺化現有 Maven 建置中發生的事情。對於 Maven 建置,您將能夠看到專案結構、正在使用的外掛、建置步驟的時間表等等。將其保留在手邊,以便在轉換專案時將其與 Gradle 建置掃描進行比較。
-
開發一種機制來驗證兩個建置產生相同的成品。
這是確保部署和測試不會中斷的重要步驟。即使是微小的變更,例如 JAR 中的明細檔內容,都可能造成問題。如果 Gradle 建置產生與 Maven 建置相同的輸出,這將讓您有信心進行切換,並讓您更容易實作將帶來最大好處的變更。
這並不表示您需要在每個階段驗證每個成品,儘管這麼做可以幫助您快速找出問題的來源。您應該專注於關鍵輸出,例如最終報告和已發布或部署的成品。
您需要考量 Gradle 與 Maven 產生的建置輸出中一些固有的差異。產生的 POM 只會包含使用時所需的資訊,而且會針對該情境正確使用
<compile>
和<runtime>
範圍。您也可能會看到檔案於封存檔中的順序,以及類別路徑中檔案的順序有所不同。大多數的差異都很小,但找出它們並驗證它們是可以接受的,這是有價值的。 -
這將建立您所需的所有 Gradle 建置檔案,即使是 多模組建置 也是如此。對於較簡單的 Maven 專案,Gradle 建置會準備好執行!
-
建置掃描將讓您更容易視覺化建置中發生的事。對於 Gradle 建置,您將能夠看到專案結構、相依性(常規和專案間)、正在使用的外掛,以及建置的主控台輸出。
您的建置可能在此時失敗,但沒關係;掃描仍然會執行。將 Gradle 建置的建置掃描與 Maven 建置的建置掃描進行比較,並繼續往下查看此清單以排除故障。
我們建議您在遷移期間定期產生建置掃描,以幫助您找出並排除問題。如果您願意,您也可以使用 Gradle 建置掃描找出 改善建置效能 的機會。
-
許多測試可以透過設定額外的來源集來輕鬆遷移。如果您使用的是第三方程式庫,例如 FitNesse,請查看 Gradle 外掛入口網站 上是否有合適的社群外掛可用。
-
以 Gradle 等效項取代 Maven 外掛。
對於 熱門外掛,Gradle 通常有您可以使用的等效外掛。您可能也會發現您可以 以內建 Gradle 功能取代外掛。作為最後的手段,您可能需要透過您自己的自訂外掛和任務類型來 重新實作 Maven 外掛。
本章節的其餘部分將更詳細地探討從 Maven 遷移至 Gradle 的建置特定面向。
了解建置生命週期
Maven 建置基於 建置生命週期 的概念,其中包含一組固定階段。這對遷移至 Gradle 的使用者來說可能是一項挑戰,因為建置生命週期是一個 新概念。儘管了解 Gradle 建置如何符合 初始化、設定和 執行 階段的結構非常重要,但 Gradle 提供了一個輔助功能,可以模擬 Maven 的階段:生命週期任務。
此功能允許您透過建立不執行動作的任務來定義自己的「生命週期」,這些任務僅依賴於您有興趣的任務。為了讓 Maven 使用者更容易轉換至 Gradle,基本外掛(由所有 JVM 語言外掛套用,例如 Java 函式庫外掛)提供了一組與主要 Maven 階段對應的生命週期任務。
以下是部分主要 Maven 階段及其對應的 Gradle 任務清單
clean
-
使用基本外掛提供的
clean
任務。 compile
-
使用 Java 外掛和其他 JVM 語言外掛提供的
classes
任務。這會編譯所有語言的所有原始檔的所有類別,並透過processResources
任務執行 資源篩選。 test
-
使用 Java 外掛提供的
test
任務。它會執行單元測試,更具體地說,是組成test
原始檔組 的測試。 package
-
使用基本外掛提供的
assemble
任務。這會建置專案的適當套件;例如,Java 函式庫的 JAR 或傳統 Java 網路應用程式的 WAR。 verify
-
使用基本外掛提供的
check
任務。這會執行附加到其上的所有驗證任務,通常包括單元測試、任何靜態分析任務(例如 Checkstyle)和其他任務。如果您要包含整合測試,您必須 手動設定這些測試。 install
-
使用 Maven 發行外掛提供的
publishToMavenLocal
任務。請注意,Gradle 建置不需要您「安裝」人工製品,因為您可以存取更適當的功能,例如 專案間相依性 和 複合建置。您應該只使用
publishToMavenLocal
來與 Maven 建置進行互操作。Gradle 也允許您根據 宣告存放庫 區段中所述,針對本機 Maven 快取解析相依性。
部署
-
使用 Maven 發佈外掛程式 所提供的
publish
任務,如果您建置使用較舊的 Maven 外掛程式(ID:maven
),請務必從中切換。這會將您的套件發佈到所有已設定的發佈存放庫。還有一些任務允許您發佈到單一存放庫,即使已定義多個存放庫也是如此。請注意,Maven 發佈外掛程式預設不會發佈原始碼和 Javadoc JAR,但這可以輕鬆啟用,如 建置 java 專案指南 中所述。
執行自動轉換
> gradle init
從根專案目錄。這包括剖析現有的 POM 並產生對應的 Gradle 建置指令碼。如果您要移轉 多專案建置,Gradle 也會建立設定指令碼。
您會發現新的 Gradle 建置包含下列內容
請參閱 建置初始化外掛程式章節,以取得自動轉換功能的完整清單。
需要記住的一件事是,組件不會自動轉換。此額外轉換需要一些手動工作。選項包括
-
使用 發行外掛程式
-
使用 應用程式外掛程式
-
使用 Gradle 外掛入口網站 中合適的社群外掛
如果您的 Maven 建置沒有很多外掛或自訂步驟,您可以簡單地執行
> gradle build
在遷移完成後。這將執行測試並自動產生所需的成品。
遷移相依性
Gradle 的相依性管理系統比 Maven 的更靈活,但它仍支援相同的概念,例如儲存庫、宣告的相依性、範圍(Gradle 中的相依性組態)和遞移相依性。事實上,Gradle 與相容 Maven 的儲存庫搭配運作,這使得遷移您的相依性變得容易。
這兩個工具之間一個顯著的差異在於它們管理版本衝突的方式。Maven 使用「最接近」的比對演算法,而 Gradle 選擇最新的。不過不用擔心,您可以控制選擇哪些版本,如 管理遞移相依性 中所述。 |
在以下各節中,我們將展示如何遷移 Maven 建置相依性管理資訊中最常見的元素。
宣告相依性
Gradle 使用與 Maven 相同的相依性識別元件:群組 ID、成品 ID 和版本。它也支援分類器。您需要做的就是將相依性的識別資訊替換為 Gradle 的語法,這在 宣告相依性 章節中有所說明。
例如,考慮這個對 Log4J 的 Maven 風格相依性
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
這個相依性在 Gradle 建置指令碼中看起來像這樣
dependencies {
implementation("log4j:log4j:1.2.12") (1)
}
dependencies {
implementation 'log4j:log4j:1.2.12' (1)
}
1 | 將 Log4J 的版本 1.2.12 附加到 implementation 組態(範圍) |
字串識別碼採用 groupId
、artifactId
和 version
的 Maven 值,儘管 Gradle 將它們稱為 group
、module
和 version
。
上述範例引發了一個明顯的問題:什麼是 implementation
組態?它是 Java 外掛 提供的標準相依性組態之一,通常用作 Maven 預設 compile
範圍的替代品。
Maven 的範圍和 Gradle 的標準組態之間的幾個差異歸結為 Gradle 區分建置模組所需的相依性和建置依賴於它的模組所需的相依性。Maven 沒有這樣的區別,因此已發佈的 POM 通常包含使用者實際上不需要的相依性。
以下是 Maven 的主要相依性範圍以及您應該如何處理它們的遷移
compile
-
Gradle 有兩個組態可以用來取代
compile
範圍:implementation
和api
。前者可用於任何套用 Java 外掛的專案,而api
僅可用於特別套用 Java 函式庫外掛 的專案。在多數情況下,你應該只使用
implementation
設定,特別是如果你正在建構應用程式或網頁應用程式時。但如果你正在建構函式庫,你可以從 建構 Java 函式庫 章節中瞭解哪些相依性應該使用api
宣告。上述連結的 Java 函式庫外掛程式章節中提供了更多關於api
和implementation
之間差異的資訊。 執行時期
-
使用
runtimeOnly
設定。 test
-
Gradle 區分需要用來編譯專案測試的相依性,以及只需要用來執行測試的相依性。
用於測試編譯的相依性應該針對
testImplementation
設定宣告。而只需要用於執行測試的相依性則應該使用testRuntimeOnly
。 已提供
-
使用
compileOnly
設定。請注意,War 外掛程式 會新增
providedCompile
和providedRuntime
相依性設定。這些設定的行為與compileOnly
稍微不同,它們只會確保這些相依性不會封裝在 WAR 檔案中。然而,這些相依性會包含在執行時期和測試執行時期類別路徑中,因此如果你需要這種行為,請使用這些設定。 匯入
-
import
範圍主要用於<dependencyManagement>
區塊中,並且僅適用於僅 POM 的出版品。請閱讀 使用物料清單 章節,以瞭解如何複製此行為的更多資訊。你也可以對僅 POM 的出版品指定常規相依性。在這種情況下,在該 POM 中宣告的相依性會被視為建置的正常傳遞相依性。
例如,假設你想要為你的測試使用
groovy-all
POM。它是一個僅 POM 的出版品,其相依性列在<dependencies>
區塊中。Gradle 建置中的適當設定如下所示範例 2. 使用僅 POM 的相依性build.gradle.ktsdependencies { testImplementation("org.codehaus.groovy:groovy-all:2.5.4") }
build.gradledependencies { testImplementation 'org.codehaus.groovy:groovy-all:2.5.4' }
這樣做的結果是,
groovy-all
POM 中的所有compile
和runtime
範圍相依性都會新增到測試執行時期類別路徑中,而只有compile
範圍相依性會新增到測試編譯類別路徑中。具有其他範圍的相依性將會被忽略。
宣告儲存庫
Gradle 允許您從任何相容於 Maven 或 Ivy 的儲存庫中擷取已宣告的相依性。與 Maven 不同,它沒有預設儲存庫,因此您必須至少宣告一個。若要讓您的 Gradle 建置具有與 Maven 建置相同的行為,請在您的 Gradle 建置中設定 Maven Central,如下所示
repositories {
mavenCentral()
}
repositories {
mavenCentral()
}
您也可以使用 repositories {}
區塊來設定自訂儲存庫,如 儲存庫類型 章節所述。
最後,Gradle 允許您針對 本機 Maven 快取/儲存庫 解析相依性。這有助於 Gradle 建置與 Maven 建置互通,但若您不需要這種互通性,則不應使用此技術。如果您想要透過檔案系統分享已發布的成品,請考慮設定一個 自訂 Maven 儲存庫,網址為 file://
。
您可能也有興趣瞭解 Gradle 自有的 相依性快取,其行為比 Maven 的更可靠,且可安全地由多個同時進行的 Gradle 程序使用。
控制相依性版本
傳遞相依性的存在表示您很容易在您的相依性圖中得到多個相同相依性的版本。預設情況下,Gradle 會在圖中挑選最新版本的相依性,但這並不總是正確的解決方案。這就是為什麼它提供多種機制來控制解析哪個版本的特定相依性。
在每個專案的基礎上,您可以使用
在 控制傳遞相依性 章節中列出了更多專門選項。
如果您希望確保多專案建置中所有專案的版本一致性,類似於 Maven 中的 <dependencyManagement>
區塊運作的方式,您可以使用 Java Platform Plugin。這允許您宣告一組可套用至多個專案的相依性約束。您甚至可以將平台發布為 Maven BOM 或使用 Gradle 的元資料格式。請參閱外掛程式頁面,以取得更多關於如何這樣做的資訊,特別是 使用平台 的區段,以了解如何將平台套用至同一建置中的其他專案。
使用物料清單 (BOM)
Maven 允許您透過在封裝類型為 pom
的 POM 檔案的 <dependencyManagement>
區段中定義相依性,來分享相依性限制。然後可以將這種特殊類型的 POM (BOM) 匯入其他 POM,以便在您的專案中擁有相容的程式庫版本。
Gradle 可以使用此類 BOM 來達成相同目的,使用基於 platform() 和 enforcedPlatform() 方法的特殊相依性語法。您只需以一般方式宣告相依性,但將相依性識別碼包覆在適當的方法中,如下面的範例所示,它「匯入」Spring Boot 相依性 BOM
dependencies {
implementation(platform("org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE")) (1)
implementation("com.google.code.gson:gson") (2)
implementation("dom4j:dom4j")
}
dependencies {
implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE') (1)
implementation 'com.google.code.gson:gson' (2)
implementation 'dom4j:dom4j'
}
1 | 套用 Spring Boot 相依性 BOM |
2 | 新增相依性,其版本由該 BOM 定義 |
您可以在 從 Maven BOM 匯入版本建議 的區段中進一步了解此功能,以及 platform()
和 enforcedPlatform()
之間的差異。
您可以使用此功能將任何相依性的 POM 中的 <dependencyManagement> 資訊套用到 Gradle 建置,即使那些封裝類型不是 pom 的相依性也是如此。platform() 和 enforcedPlatform() 都會忽略在 <dependencies> 區塊中宣告的任何相依性。
|
移轉多模組建置 (專案聚合)
若要移轉多模組 Maven 建置,只需執行下列步驟
-
建立與根 POM 的
<modules>
區塊相符的設定指令碼。例如,這個
<modules>
區塊<modules> <module>simple-weather</module> <module>simple-webapp</module> </modules>
可以透過將下列程式碼行新增到設定指令碼中來移轉
範例 5. 宣告哪些專案是建置的一部分settings.gradle.ktsrootProject.name = "simple-multi-module" (1) include("simple-weather", "simple-webapp") (2)
settings.gradlerootProject.name = 'simple-multi-module' (1) include 'simple-weather', 'simple-webapp' (2)
1 設定整體專案名稱 2 將兩個子專案設定為此組建的一部分 gradle 專案
的輸出> gradle projects ------------------------------------------------------------ Root project 'simple-multi-module' ------------------------------------------------------------ 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
-
以 專案相依性 取代跨模組相依性。
-
以 慣例外掛程式 複製專案繼承。
這基本上包括建立一個根專案組建指令碼,將共用設定注入到適當的子專案中。
移轉 Maven 設定檔和屬性
Maven 允許您使用各種屬性參數化組建。有些是專案模型的唯讀屬性,其他則是在 POM 中由使用者定義的。它甚至允許您將系統屬性視為專案屬性。
Gradle 有類似的專案屬性系統,儘管它區分了這些屬性和系統屬性。例如,您可以在下列位置定義屬性:
-
組建指令碼
-
根專案目錄中的
gradle.properties
檔案 -
$HOME/.gradle
目錄中的gradle.properties
檔案
這些不是唯一的選項,因此如果您有興趣進一步瞭解如何以及可以在哪裡定義屬性,請查看 組建環境 章節。
您需要了解的一項重要行為是,當同一個屬性同時在組建指令碼和其中一個外部屬性檔案中定義時會發生什麼事:組建指令碼值優先。始終如此。幸運的是,您可以模仿設定檔的概念,以提供可覆寫的預設值。
這讓我們了解 Maven 設定檔。這些是一種根據環境、目標平台或任何其他類似因素啟用和停用不同設定的方式。在邏輯上,它們只不過是有限的 if
陳述式。由於 Gradle 有更強大的方式來宣告條件,因此它不需要正式支援設定檔(除了相依性的 POM 之外)。您可以輕鬆地將條件與次要組建指令碼結合,以取得相同的行為,您將會看到。
假設您有不同的部署設定,取決於環境:本機開發(預設)、測試環境和生產環境。若要新增類似設定檔的行為,請先在專案根目錄中為每個環境建立建置指令碼:profile-default.gradle
、profile-test.gradle
和 profile-prod.gradle
。然後,您可以根據您自己選擇的 專案屬性,有條件地套用其中一個設定檔指令碼。
下列範例示範使用稱為 buildProfile
的專案屬性,以及只初始化稱為 message
的 額外專案屬性 的設定檔指令碼的基本技巧
val buildProfile: String? by project (1)
apply(from = "profile-${buildProfile ?: "default"}.gradle.kts") (2)
tasks.register("greeting") {
// Store the message into a variable, because referencing extras from the task action
// is not compatible with the configuration cache.
val message = project.extra["message"]
doLast {
println(message) (3)
}
}
val message by extra("foobar") (4)
val message by extra("testing 1 2 3") (4)
val message by extra("Hello, world!") (4)
if (!hasProperty('buildProfile')) ext.buildProfile = 'default' (1)
apply from: "profile-${buildProfile}.gradle" (2)
tasks.register('greeting') {
// Store the message into a variable, because referencing extras from the task action
// is not compatible with the configuration cache.
def message = project.message
doLast {
println message (3)
}
}
ext.message = 'foobar' (4)
ext.message = 'testing 1 2 3' (4)
ext.message = 'Hello, world!' (4)
1 | 檢查 (Groovy) 或繫結 (Kotlin) buildProfile 專案屬性的存在 |
2 | 套用適當的設定檔指令碼,使用指令碼檔名中的 buildProfile 值 |
3 | 列印 message 額外專案屬性的值 |
4 | 初始化 message 額外專案屬性,其值可以在主建置指令碼中使用 |
有了這個設定,您可以透過傳遞專案屬性的值來啟用其中一個設定檔,在本例中為 buildProfile
gradle greeting
的輸出> gradle greeting foobar
gradle -PbuildProfile=test greeting
的輸出> gradle -PbuildProfile=test greeting testing 1 2 3
您不限於檢查專案屬性。您也可以檢查環境變數、JDK 版本、執行建置的作業系統,或任何您能想到的其他內容。
需要注意的一件事是,高階條件陳述式會讓建置更難理解和維護,類似於它們使物件導向程式碼複雜化的方式。設定檔也適用相同的原則。Gradle 為您提供了許多更好的方法來避免 Maven 經常需要的廣泛使用設定檔,例如透過設定多個彼此為變體的任務。請參閱 Maven 發佈外掛程式 建立的 publishPubNamePublicationToRepoNameRepository
任務。
若要深入探討在 Gradle 中使用 Maven 設定檔,請直接參閱 這篇部落格文章。
過濾資源
Maven 有個稱為 process-resources
的階段,預設會將目標 resources:resources
與它連結。這讓建置作者有機會對各種檔案執行變數替換,例如網頁資源、封裝的屬性檔案等。
Gradle 的 Java 外掛提供一個 processResources
任務來執行相同的工作。這個 ProcessResources 任務會將檔案從設定的資源目錄(預設為 src/main/resources
)複製到輸出目錄。而且就像任何 ProcessResources
或 Copy
任務一樣,你可以設定它來執行 檔案過濾、重新命名 和 內容過濾。
以下是一個範例設定,它將原始檔案視為 Groovy SimpleTemplateEngine
範本,並提供 version
和 buildNumber
屬性給這些範本
tasks {
processResources {
expand("version" to version, "buildNumber" to currentBuildNumber)
}
}
processResources {
expand(version: version, buildNumber: currentBuildNumber)
}
請參閱 CopySpec 的 API 文件,以查看所有可用的選項。
設定整合測試
許多 Maven 建置會納入某種形式的整合測試,Maven 會透過額外的階段集來支援這項功能:pre-integration-test
、integration-test
、post-integration-test
和 verify
。它也會使用 Failsafe 外掛取代 Surefire,這樣失敗的整合測試就不會自動導致建置失敗(因為你可能需要清理資源,例如正在執行的應用程式伺服器)。
這種行為很容易使用來源集在 Gradle 中複製,如我們在 Java 和 JVM 專案的測試 章節中所說明。然後你可以設定一個清理任務,例如關閉測試伺服器,以在整合測試之後始終執行,無論它們是否成功或失敗,方法是使用 Task.finalizedBy()。
如果你真的不希望整合測試導致建置失敗,那麼你可以使用 Test.ignoreFailures 設定,如 Java 測試章節的 測試執行 部分所述。
來源集也讓你對整合測試的原始檔案放置位置有很大的彈性。你可以輕鬆地將它們放在與單元測試相同的目錄中,或者更理想的做法是放在一個獨立的來源目錄中,例如 src/integTest/java
。若要支援其他類型的測試,只需新增更多來源集和 測試 任務即可。
移轉常見外掛
Maven 和 Gradle 共用一種透過外掛擴充建置的常見方法。儘管外掛系統在表面下非常不同,但它們共用許多基於功能的外掛,例如
-
Shade/Shadow
-
Jetty
-
Checkstyle
-
JaCoCo
-
AntRun(請參閱下方)
這為何重要?因為許多外掛依賴於標準 Java 慣例,移轉只是複製 Maven 外掛在 Gradle 中的組態問題。舉例來說,以下是簡單的 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 組態如下
checkstyle {
config = resources.text.fromFile("checkstyle.xml", "UTF-8")
isShowViolations = true
isIgnoreFailures = false
}
checkstyle {
config = resources.text.fromFile('checkstyle.xml', 'UTF-8')
showViolations = true
ignoreFailures = false
}
Checkstyle 工作會自動新增為 check
工作的相依項,其中也包括 test
。如果您要確保 Checkstyle 在測試前執行,請使用 mustRunAfter(…) 方法指定順序
checkstyle
工作何時執行tasks {
test {
mustRunAfter(checkstyleMain, checkstyleTest)
}
}
test.mustRunAfter checkstyleMain, checkstyleTest
您會看到,Gradle 組態通常比 Maven 等效組態短很多。您也有更靈活的執行模型,因為您不再受限於 Maven 的固定階段。
在從 Maven 移轉專案時,別忘了來源組。這些來源組通常提供比 Maven 更優雅的解決方案來處理整合測試或產生來源,因此您應該將它們納入您的移轉計畫。
Ant 目標
許多 Maven 建置依賴於 AntRun 外掛,以自訂建置,而不會實作自訂 Maven 外掛的負擔。Gradle 沒有等效外掛,因為 Ant 是 Gradle 建置中的一等公民,透過 ant
物件。例如,您可以像這樣使用 Ant 的 Echo 工作
tasks.register("sayHello") {
doLast {
ant.withGroovyBuilder {
"echo"("message" to "Hello!")
}
}
}
tasks.register('sayHello') {
doLast {
ant.echo message: 'Hello!'
}
}
甚至 Ant 屬性和檔案集也原生支援。如需深入了解,請參閱 從 Gradle 使用 Ant。
了解您不需要哪些外掛
值得注意的是,Gradle 建置通常比 Maven 的建置更容易擴充和自訂。在此脈絡中,表示您可能不需要 Gradle 外掛程式來取代 Maven 的外掛程式。例如,Maven Enforcer 外掛程式讓您可以控制相依性版本和環境因素,但這些內容可以在一般的 Gradle 建置指令碼中輕鬆設定。
處理不常見和自訂外掛程式
您可能會遇到在 Gradle 中沒有對應項的 Maven 外掛程式,特別是如果您或組織中的某人撰寫了自訂外掛程式時。此類案例仰賴您了解 Gradle(和潛在的 Maven)運作方式,因為您通常必須撰寫自己的外掛程式。
在遷移目的方面,有兩種主要的 Maven 外掛程式類型
-
使用 Maven 專案物件的類型。
-
不使用 Maven 專案物件的類型。
這點為何重要?因為如果您使用後者的其中一個類型,您可以輕易地將其重新實作為 自訂 Gradle 任務類型。只要定義與 mojo 參數對應的任務輸入和輸出,並將執行邏輯轉換為任務動作即可。
如果外掛程式依賴於 Maven 專案,則您必須重新撰寫它。不要從考慮 Maven 外掛程式如何運作開始,而是觀察它嘗試解決的問題。然後嘗試找出如何在 Gradle 中解決該問題。您可能會發現這兩個建置模型有足夠的差異,以至於將 Maven 外掛程式程式碼「轉錄」到 Gradle 外掛程式中不會有效。好處是,由於 Gradle 具有更豐富的建置模型和 API,因此外掛程式可能會比原始 Maven 外掛程式更容易撰寫。
如果您確實需要透過建置指令碼或外掛程式實作自訂邏輯,請查看與外掛程式開發相關的指南。此外,務必熟悉 Gradle 的Groovy DSL 參考,其中提供了您將使用之 API 的完整文件。它詳細說明了標準設定區塊(以及它們所備份的物件)、系統中的核心類型(Project
、Task
等)以及標準任務類型集合。主要進入點是Project介面,因為它是備份建置指令碼的頂層物件。
進一步閱讀
本章節涵蓋了將 Maven 建置移轉到 Gradle 的主要主題。剩下的只有一些在移轉期間或移轉後可能會有用的其他領域
-
瞭解如何設定 Gradle 的建置環境,包括用於執行它的 JVM 設定
-
瞭解如何有效地建構您的建置
-
設定 Gradle 的記錄並從您的建置中使用它
最後,本指南僅介紹了 Gradle 的一些功能,我們鼓勵您從使用者手冊的其他章節和我們的逐步範例中瞭解其餘功能。