從 Apache Maven 遷移建置
Apache Maven 是一個用於 Java 和其他 JVM 基礎專案的建置工具。將現有的 Maven 建置遷移到 Gradle 是很常見的做法。
本指南將透過解釋這兩個工具之間的差異和相似之處,並提供您可以遵循的步驟來簡化流程,以協助您進行此類遷移。
提出遷移的理由
Gradle 和 Maven 之間的主要差異在於彈性、效能、使用者體驗和相依性管理。
在Maven 與 Gradle 功能比較中,您可以找到這些方面的視覺化概觀。
一般指南
Gradle 和 Maven 對於如何建置專案有著根本不同的觀點。Gradle 提供了彈性且可擴展的建置模型,該模型將實際工作委派給任務圖的執行。Maven 使用固定的線性階段模型,您可以在其中附加目標(執行工作的事物)。這可能會使兩者之間的遷移看起來令人生畏,但遷移可能出乎意料地容易,因為 Gradle 遵循與 Maven 相同的許多慣例,例如標準專案結構,並且其相依性管理的工作方式也類似。
在此,我們列出一系列步驟供您遵循,這將有助於促進將任何 Maven 建置遷移到 Gradle
將舊的 Maven 建置和新的 Gradle 建置並排放置。您知道 Maven 建置可以運作,因此在您確信 Gradle 建置產生所有相同的成品之前,您應該保留它。這也意味著使用者可以嘗試 Gradle 建置,而無需建立原始碼樹的新副本。 |
-
建置掃描將使您更容易視覺化現有 Maven 建置中發生的情況。對於 Maven 建置,您將能夠看到專案結構、正在使用的外掛、建置步驟的時間軸等等。請隨時保留此資訊,以便在轉換專案時將其與 Gradle 建置掃描進行比較。
-
開發一種機制來驗證兩個建置是否產生相同的成品。
這是至關重要的一步,以確保您的部署和測試不會中斷。即使是小的變更,例如 JAR 中 manifest 檔案的內容,也可能導致問題。如果您的 Gradle 建置產生與 Maven 建置相同的輸出,這將使您對切換更有信心,並使實作將提供最大效益的變更更容易。
這並不表示您需要在每個階段驗證每個成品,儘管這樣做可以幫助您快速找出問題的根源。您應該專注於關鍵輸出,例如最終報告以及發佈或部署的成品。
您將需要考慮 Gradle 產生的建置輸出與 Maven 相比的一些固有差異。產生的 POM 將僅包含消費所需的資訊,並且它們將針對該情境正確使用
<compile>
和<runtime>
範圍。您也可能會看到封存檔案中檔案的順序以及類別路徑上檔案的順序有所不同。大多數差異將是微小的,但值得找出這些差異並驗證它們是否可以接受。 -
這將建立您需要的所有 Gradle 建置檔案,即使是多模組建置也是如此。對於較簡單的 Maven 專案,Gradle 建置將準備好執行!
-
建置掃描將使您更容易視覺化建置中發生的情況。對於 Gradle 建置,您將能夠看到專案結構、相依性(常規相依性和專案間相依性)、正在使用的外掛以及建置的控制台輸出。
您的建置可能在此時失敗,但沒關係;掃描仍將執行。將 Gradle 建置的建置掃描與 Maven 建置的建置掃描進行比較,然後繼續按照此列表向下排解故障。
我們建議您在遷移期間定期產生建置掃描,以幫助您找出並排解問題。如果您願意,您也可以使用 Gradle 建置掃描來找出提升建置效能的機會。
-
許多測試可以透過配置額外的原始碼集來輕鬆遷移。如果您正在使用第三方函式庫,例如 FitNesse,請查看 Gradle 外掛入口網站上是否有合適的社群外掛可用。
-
將 Maven 外掛替換為 Gradle 等效外掛。
對於流行的外掛,Gradle 通常具有您可以使用的等效外掛。您也可能會發現您可以使用內建的 Gradle 功能替換外掛。作為最後的手段,您可能需要透過您自己的自訂外掛和任務類型重新實作 Maven 外掛。
本章的其餘部分將更詳細地探討從 Maven 遷移建置到 Gradle 的特定方面。
了解建置生命週期
Maven 建置基於 建置生命週期 的概念,該生命週期由一組固定的階段組成。這對於遷移到 Gradle 的使用者來說可能是一個挑戰,因為建置生命週期是一個新概念。儘管了解 Gradle 建置如何融入初始化、配置和執行階段的結構非常重要,但 Gradle 提供了一個輔助功能,可以模擬 Maven 的階段:生命週期任務。
此功能允許您透過建立不執行任何動作的任務來定義自己的「生命週期」,這些任務僅依賴於您感興趣的任務。為了使 Maven 使用者更容易過渡到 Gradle,Base 外掛(由所有 JVM 語言外掛(例如 Java Library 外掛)套用)提供了一組生命週期任務,這些任務對應於主要的 Maven 階段。
以下是一些主要 Maven 階段及其對應的 Gradle 任務的列表
clean
-
使用 Base 外掛提供的
clean
任務。 compile
-
使用 Java 外掛和其他 JVM 語言外掛提供的
classes
任務。這會編譯所有語言的所有原始檔的所有類別,並透過processResources
任務執行資源篩選。 test
-
使用 Java 外掛提供的
test
任務。它會執行單元測試,更具體地說,會執行構成test
原始碼集 的測試。 package
-
使用 Base 外掛提供的
assemble
任務。這會建置專案的適當套件;例如,Java 函式庫的 JAR 或傳統 Java Web 應用程式的 WAR。 verify
-
使用 Base 外掛提供的
check
任務。這會執行附加到它的所有驗證任務,通常包括單元測試、任何靜態分析任務(例如 Checkstyle)和其他任務。如果您想包含整合測試,則必須手動配置這些測試。 install
-
使用 Maven Publish 外掛提供的
publishToMavenLocal
任務。Gradle 也允許您根據本機 Maven 快取解析相依性,如宣告儲存庫章節中所述。
deploy
-
使用 Maven Publish 外掛提供的
publish
任務,確保您切換到較舊的 Maven 外掛 (ID:maven
)(如果您的建置正在使用該外掛)。這會將您的套件發佈到所有配置的發佈儲存庫。即使定義了多個儲存庫,也有任務允許您發佈到單個儲存庫。請注意,Maven Publish 外掛預設不會發佈 原始碼和 Javadoc JAR,但可以輕鬆啟用此功能,如 建置 Java 專案指南中所述。
執行自動轉換
Gradle 的 init
任務 通常用於建立新的骨架專案,但您也可以使用它來自動將現有的 Maven 建置轉換為 Gradle。一旦 Gradle 安裝在您的系統上,您所要做的就是執行命令
> gradle init
從根專案目錄。這包括剖析現有的 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 相同的相依性識別碼組件:群組 ID、成品 ID 和版本。它也支援分類器。您需要做的就是將相依性的識別碼資訊替換為 Gradle 的語法,該語法在宣告相依性章節中進行了描述。
例如,考慮以下 Maven 樣式的 Log4J 相依性
<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 Library 外掛 的專案。在大多數情況下,您應該直接使用
implementation
配置,特別是如果您正在建置應用程式或 Web 應用程式。但是,如果您正在建置函式庫,您可以在關於建置 Java 函式庫的章節中了解應使用api
宣告哪些相依性。上面連結的 Java Library 外掛章節中提供了關於api
和implementation
之間差異的更多資訊。 runtime
-
使用
runtimeOnly
配置。 test
-
Gradle 區分了編譯專案測試所需的相依性和僅執行測試所需的相依性。
編譯測試所需的相依性應針對
testImplementation
配置宣告。僅執行測試所需的相依性應使用testRuntimeOnly
。 provided
-
使用
compileOnly
配置。請注意,War 外掛新增了
providedCompile
和providedRuntime
相依性配置。這些配置的行為與compileOnly
略有不同,只是確保這些相依性未封裝在 WAR 檔案中。但是,這些相依性包含在執行階段和測試執行階段類別路徑中,因此如果這是您需要的行為,請使用這些配置。 import
-
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 不同,它沒有預設儲存庫,因此您必須至少宣告一個。為了與您的 Maven 建置具有相同的行為,只需在您的 Gradle 建置中配置Maven Central,如下所示
repositories {
mavenCentral()
}
repositories {
mavenCentral()
}
您也可以使用 repositories {}
區塊來配置自訂儲存庫,如儲存庫類型章節中所述。
最後,Gradle 允許您根據本機 Maven 快取/儲存庫解析相依性。這有助於 Gradle 建置與 Maven 建置互操作,但如果您不需要該互操作性,則不應使用此技術。如果您想透過檔案系統共享發佈的成品,請考慮配置具有 file://
URL 的自訂 Maven 儲存庫。
您也可能對了解 Gradle 自己的相依性快取感興趣,該快取的行為比 Maven 更可靠,並且可以安全地被多個並發 Gradle 程序使用。
控制相依性版本
傳遞相依性的存在意味著您很容易在相依性圖中最終得到同一相依性的多個版本。預設情況下,Gradle 將在圖中選擇相依性的最新版本,但這並不總是正確的解決方案。這就是為什麼它提供了幾種機制來控制解析給定相依性的哪個版本。
在每個專案的基礎上,您可以使用
在控制傳遞相依性章節中列出了更多更專業的選項。
如果您想確保多專案建置中所有專案的版本一致性,類似於 Maven 中 <dependencyManagement>
區塊的工作方式,您可以使用 Java Platform 外掛。這允許您宣告一組可以應用於多個專案的相依性約束。您甚至可以將平台發佈為 Maven BOM 或使用 Gradle 的 metadata 格式。請參閱外掛頁面以獲取有關如何執行此操作的更多資訊,特別是關於消費平台的章節,以了解如何將平台應用於同一建置中的其他專案。
使用物料清單 (BOM)
Maven 允許您透過在 packaging 類型為 pom
的 POM 檔案的 <dependencyManagement>
區段中定義相依性來共享相依性約束。然後可以將這種特殊類型的 POM (BOM) 匯入到其他 POM 中,以便您在專案中擁有一致的函式庫版本。
Gradle 可以使用 BOM 來達到相同的目的,方法是使用基於 platform() 和 enforcedPlatform() 方法的特殊依賴語法。您只需以正常方式宣告依賴,但將依賴識別符包裝在適當的方法中,如此範例所示,該範例「匯入」了 Spring Boot Dependencies 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 Dependencies 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 projects
的輸出> gradle projects 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
會繫結到該階段。這讓建置作者有機會對各種檔案執行變數替換,例如 Web 資源、封裝的屬性檔案等。
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()。
如果您真的不希望整合測試使建置失敗,那麼您可以使用 Java 測試章節的測試執行區段中描述的 Test.ignoreFailures 設定。
來源集還為您提供了很大的彈性,讓您可以將整合測試的來源檔案放置在任何位置。您可以輕鬆地將它們與單元測試放在同一個目錄中,或者更理想地,放在一個單獨的來源目錄中,例如 src/integTest/java
。為了支援其他類型的測試,只需新增更多來源集和 Test 任務即可。
遷移常見外掛程式
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 組態如下
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 屬性和 fileset 也受到原生支援。若要瞭解更多資訊,請參閱從 Gradle 使用 Ant。
了解哪些外掛程式是不必要的
值得記住的是,Gradle 建置通常比 Maven 建置更容易擴充和自訂。在這種情況下,這表示您可能不需要 Gradle 外掛程式來取代 Maven 外掛程式。例如,Maven Enforcer 外掛程式允許您控制依賴版本和環境因素,但這些都可以在正常的 Gradle 建置腳本中輕鬆設定。
處理不常見和自訂外掛程式
您可能會遇到在 Gradle 中沒有對應項的 Maven 外掛程式,特別是如果您或您組織中的某人編寫了自訂外掛程式。這種情況取決於您對 Gradle(以及可能還有 Maven)運作方式的理解,因為您通常必須編寫自己的外掛程式。
就遷移而言,有兩種主要類型的 Maven 外掛程式
-
使用 Maven 專案物件的外掛程式。
-
不使用 Maven 專案物件的外掛程式。
為什麼這很重要?因為如果您使用後者之一,您可以輕鬆地將其重新實作為自訂 Gradle 任務類型。只需定義與 mojo 參數對應的任務輸入和輸出,並將執行邏輯轉換為任務動作即可。
如果外掛程式依賴 Maven 專案,那麼您將必須重寫它。不要從考慮 Maven 外掛程式如何運作開始,而是看看它試圖解決什麼問題。然後嘗試找出如何在 Gradle 中解決該問題。您可能會發現,這兩個建置模型非常不同,「轉錄」Maven 外掛程式程式碼到 Gradle 外掛程式中根本不會有效。從好的方面來說,外掛程式可能比原始 Maven 外掛程式更容易編寫,因為 Gradle 具有更豐富的建置模型和 API。
如果您確實需要實作自訂邏輯,無論是透過建置腳本還是外掛程式,請查看與外掛程式開發相關的指南。另請務必熟悉 Gradle 的 Groovy DSL 參考,其中提供了您將使用的 API 的完整文件。它詳細說明了標準組態區塊(以及支援它們的物件)、系統中的核心類型(Project
、Task
等)以及標準任務類型集。主要入口點是 Project 介面,因為它是支援建置腳本的頂層物件。
延伸閱讀
本章涵蓋了專門針對將 Maven 建置遷移到 Gradle 的主要主題。剩下的只是一些在遷移期間或之後可能有用的其他領域
-
了解如何設定 Gradle 的建置環境,包括用於執行它的 JVM 設定
-
了解如何有效地組織您的建置
-
設定 Gradle 的日誌記錄並從您的建置中使用它
最後,本指南僅觸及了 Gradle 的一些功能,我們鼓勵您從使用者手冊的其他章節和我們的逐步範例中了解其餘功能。