1. 程式人生 > >maven 常用外掛

maven 常用外掛

我們都知道Maven本質上是一個外掛框架,它的核心並不執行任何具體的構建任務,所有這些任務都交給外掛來完成,例如編譯原始碼是由maven- compiler-plugin完成的。進一步說,每個任務對應了一個外掛目標(goal),每個外掛會有一個或者多個目標,例如maven- compiler-plugin的compile目標用來編譯位於src/main/java/目錄下的主原始碼,testCompile目標用來編譯位於src/test/java/目錄下的測試原始碼。

使用者可以通過兩種方式呼叫Maven外掛目標。第一種方式是將外掛目標與生命週期階段(lifecycle phase)繫結,這樣使用者在命令列只是輸入生命週期階段而已,例如Maven預設將maven-compiler-plugin的compile目標與 compile生命週期階段繫結,因此命令mvn compile

實際上是先定位到compile這一生命週期階段,然後再根據繫結關係調用maven-compiler-plugin的compile目標。第二種方式是直接在命令列指定要執行的外掛目標,例如mvn archetype:generate 就表示呼叫maven-archetype-plugin的generate目標,這種帶冒號的呼叫方式與生命週期無關。

認識上述Maven外掛的基本概念能幫助你理解Maven的工作機制,不過要想更高效率地使用Maven,瞭解一些常用的外掛還是很有必要的,這可 以幫助你避免一不小心重新發明輪子。多年來Maven社群積累了大量的經驗,並隨之形成了一個成熟的外掛生態圈。Maven官方有兩個外掛列表,第一個列 表的GroupId為org.apache.maven.plugins,這裡的外掛最為成熟,具體地址為:

http://maven.apache.org/plugins/index.html。第二個列表的GroupId為org.codehaus.mojo,這裡的外掛沒有那麼核心,但也有不少十分有用,其地址為:http://mojo.codehaus.org/plugins.html

接下來筆者根據自己的經驗介紹一些最常用的Maven外掛,在不同的環境下它們各自都有其出色的表現,熟練地使用它們能讓你的日常構建工作事半功倍。

maven-antrun-plugin

maven-antrun-plugin能讓使用者在Maven專案中執行Ant任務。使用者可以直接在該外掛的配置以Ant的方式編寫Target, 然後交給該外掛的run目標去執行。在一些由Ant往Maven遷移的專案中,該外掛尤其有用。此外當你發現需要編寫一些自定義程度很高的任務,同時又覺 得Maven不夠靈活時,也可以以Ant的方式實現之。maven-antrun-plugin的run目標通常與生命週期繫結執行。

maven-archetype-plugin

Archtype指專案的骨架,Maven初學者最開始執行的Maven命令可能就是mvn archetype:generate,這實際上就是讓maven-archetype-plugin生成一個很簡單的專案骨架,幫助開發者快速上手。可能也有人看到一些文件寫了mvn archetype:create, 但實際上create目標已經被棄用了,取而代之的是generate目標,該目標使用互動式的方式提示使用者輸入必要的資訊以建立專案,體驗更好。 maven-archetype-plugin還有一些其他目標幫助使用者自己定義專案原型,例如你由一個產品需要交付給很多客戶進行二次開發,你就可以為 他們提供一個Archtype,幫助他們快速上手。

maven-assembly-plugin

maven-assembly-plugin的用途是製作專案分發包,該分發包可能包含了專案的可執行檔案、原始碼、readme、平臺指令碼等等。 maven-assembly-plugin支援各種主流的格式如zip、tar.gz、jar和war等,具體打包哪些檔案是高度可控的,例如使用者可以 按檔案級別的粒度、檔案集級別的粒度、模組級別的粒度、以及依賴級別的粒度控制打包,此外,包含和排除配置也是支援的。maven-assembly- plugin要求使用者使用一個名為assembly.xml的元資料檔案來表述打包,它的single目標可以直接在命令列呼叫,也可以被繫結至生命週期。

maven-dependency-plugin

maven-dependency-plugin最大的用途是幫助分析專案依賴,dependency:list能夠列出專案最終解析到的依賴列表,dependency:tree能進一步的描繪專案依賴樹,dependency:analyze可以告訴你專案依賴潛在的問題,如果你有直接使用到的卻未宣告的依賴,該目標就會發出警告。maven-dependency-plugin還有很多目標幫助你操作依賴檔案,例如dependency:copy-dependencies能將專案依賴從本地Maven倉庫複製到某個特定的資料夾下面。

maven-enforcer-plugin

在一個稍大一點的組織或團隊中,你無法保證所有成員都熟悉Maven,那他們做一些比較愚蠢的事情就會變得很正常,例如給專案引入了外部的 SNAPSHOT依賴而導致構建不穩定,使用了一個與大家不一致的Maven版本而經常抱怨構建出現詭異問題。maven-enforcer- plugin能夠幫助你避免之類問題,它允許你建立一系列規則強制大家遵守,包括設定Java版本、設定Maven版本、禁止某些依賴、禁止 SNAPSHOT依賴。只要在一個父POM配置規則,然後讓大家繼承,當規則遭到破壞的時候,Maven就會報錯。除了標準的規則之外,你還可以擴充套件該插 件,編寫自己的規則。maven-enforcer-plugin的enforce目標負責檢查規則,它預設繫結到生命週期的validate階段。

maven-help-plugin

maven-help-plugin是一個小巧的輔助工具,最簡單的help:system可以列印所有可用的環境變數和Java系統屬性。help:effective-pomhelp:effective-settings最 為有用,它們分別列印專案的有效POM和有效settings,有效POM是指合併了所有父POM(包括Super POM)後的XML,當你不確定POM的某些資訊從何而來時,就可以檢視有效POM。有效settings同理,特別是當你發現自己配置的 settings.xml沒有生效時,就可以用help:effective-settings來驗證。此外,maven-help-plugin的describe目標可以幫助你描述任何一個Maven外掛的資訊,還有all-profiles目標和active-profiles目標幫助檢視專案的Profile。

maven-release-plugin

maven-release-plugin的用途是幫助自動化專案版本釋出,它依賴於POM中的SCM資訊。release:prepare用來準備版本釋出,具體的工作包括檢查是否有未提交程式碼、檢查是否有SNAPSHOT依賴、升級專案的SNAPSHOT版本至RELEASE版本、為專案打標籤等等。release:perform則 是簽出標籤中的RELEASE原始碼,構建併發布。版本釋出是非常瑣碎的工作,它涉及了各種檢查,而且由於該工作僅僅是偶爾需要,因此手動操作很容易遺漏一 些細節,maven-release-plugin讓該工作變得非常快速簡便,不易出錯。maven-release-plugin的各種目標通常直接在 命令列呼叫,因為版本釋出顯然不是日常構建生命週期的一部分。

maven-resources-plugin

為了使專案結構更為清晰,Maven區別對待Java程式碼檔案和資原始檔,maven-compiler-plugin用來編譯Java程式碼,maven-resources-plugin則用來處理資原始檔。預設的主資原始檔目錄是src/main/resources,很多使用者會需要新增額外的資原始檔目錄,這個時候就可以通過配置maven-resources-plugin來實現。此外,資原始檔過濾也是Maven的一大特性,你可以在資原始檔中使用${propertyName}形式的Maven屬性,然後配置maven-resources-plugin開啟對資原始檔的過濾,之後就可以針對不同環境通過命令列或者Profile傳入屬性的值,以實現更為靈活的構建。

maven-surefire-plugin

可能是由於歷史的原因,Maven 2/3中用於執行測試的外掛不是maven-test-plugin,而是maven-surefire-plugin。其實大部分時間內,只要你的測試 類遵循通用的命令約定(以Test結尾、以TestCase結尾、或者以Test開頭),就幾乎不用知曉該外掛的存在。然而在當你想要跳過測試、排除某些 測試類、或者使用一些TestNG特性的時候,瞭解maven-surefire-plugin的一些配置選項就很有用了。例如 mvn test -Dtest=FooTest 這樣一條命令的效果是僅執行FooTest測試類,這是通過控制maven-surefire-plugin的test引數實現的。

build-helper-maven-plugin

Maven預設只允許指定一個主Java程式碼目錄和一個測試Java程式碼目錄,雖然這其實是個應當儘量遵守的約定,但偶爾你還是會希望能夠指定多個 原始碼目錄(例如為了應對遺留專案),build-helper-maven-plugin的add-source目標就是服務於這個目的,通常它被繫結到 預設生命週期的generate-sources階段以新增額外的原始碼目錄。需要強調的是,這種做法還是不推薦的,因為它破壞了 Maven的約定,而且可能會遇到其他嚴格遵守約定的外掛工具無法正確識別額外的原始碼目錄。

build-helper-maven-plugin的另一個非常有用的目標是attach-artifact,使用該目標你可以以classifier的形式選取部分專案檔案生成附屬構件,並同時install到本地倉庫,也可以deploy到遠端倉庫。

exec-maven-plugin

exec-maven-plugin很好理解,顧名思義,它能讓你執行任何本地的系統程式,在某些特定情況下,執行一個Maven外部的程式可能就是最簡單的問題解決方案,這就是exec:exec的 用途,當然,該外掛還允許你配置相關的程式執行引數。除了exec目標之外,exec-maven-plugin還提供了一個java目標,該目標要求你 提供一個mainClass引數,然後它能夠利用當前專案的依賴作為classpath,在同一個JVM中執行該mainClass。有時候,為了簡單的 演示一個命令列Java程式,你可以在POM中配置好exec-maven-plugin的相關執行引數,然後直接在命令執行 mvn exec:java 以檢視執行效果。

jetty-maven-plugin

在進行Web開發的時候,開啟瀏覽器對應用進行手動的測試幾乎是無法避免的,這種測試方法通常就是將專案打包成war檔案,然後部署到Web容器 中,再啟動容器進行驗證,這顯然十分耗時。為了幫助開發者節省時間,jetty-maven-plugin應運而生,它完全相容 Maven專案的目錄結構,能夠週期性地檢查原始檔,一旦發現變更後自動更新到內建的Jetty Web容器中。做一些基本配置後(例如Web應用的contextPath和自動掃描變更的時間間隔),你只要執行 mvn jetty:run ,然後在IDE中修改程式碼,程式碼經IDE自動編譯後產生變更,再由jetty-maven-plugin偵測到後更新至Jetty容器,這時你就可以直接 測試Web頁面了。需要注意的是,jetty-maven-plugin並不是宿主於Apache或Codehaus的官方外掛,因此使用的時候需要額外 的配置settings.xml的pluginGroups元素,將org.mortbay.jetty這個pluginGroup加入。

versions-maven-plugin

很多Maven使用者遇到過這樣一個問題,當專案包含大量模組的時候,為他們集體更新版本就變成一件煩人的事情,到底有沒有自動化工具能幫助完成這件 事情呢?(當然你可以使用sed之類的文字操作工具,不過不在本文討論範圍)答案是肯定的,versions-maven- plugin提供了很多目標幫助你管理Maven專案的各種版本資訊。例如最常用的,命令 mvn versions:set -DnewVersion=1.1-SNAPSHOT 就能幫助你把所有模組的版本更新到1.1-SNAPSHOT。該外掛還提供了其他一些很有用的目標,display-dependency- updates能告訴你專案依賴有哪些可用的更新;類似的display-plugin-updates能告訴你可用的外掛更新;然後use- latest-versions能自動幫你將所有依賴升級到最新版本。最後,如果你對所做的更改滿意,則可以使用 mvn versions:commit 提交,不滿意的話也可以使用 mvn versions:revert 進行撤銷。

小結

本文介紹了一些最常用的Maven外掛,這裡指的“常用”是指經常需要進行配置的外掛,事實上我們用Maven的時候很多其它外掛也是必須的,例如 預設的編譯外掛maven-compiler-plugin和預設的打包外掛maven-jar-plugin,但因為很少需要對它們進行配置,因此不在 本文討論範圍。瞭解常用的Maven外掛能幫助你事倍功半地完成專案構建任務,反之你就可能會因為經常遇到一些難以解決的問題而感到沮喪。本文介紹的外掛 基本能覆蓋大部分Maven使用者的日常使用需要,如果你真有非常特殊的需求,自行編寫一個Maven外掛也不是難事,更何況還有這麼多開放原始碼的外掛供 你參考。