Maven的基本原理和新特性

 用Maven做項目管理
在Java世界中我們很多的開發人員選擇用Ant來構建項目,一個build.xml能夠完成編譯、測試、打包、部署等很多任務,但我們也碰到了很多的問題,如jar文件管理混亂,各個項目結構和build.xml相差很大等等。而Maven的出現,給項目提供了更多的支持。
1        簡介
Maven作爲Apache的一個開源項目,旨在給項目管理提供更多的支持,主頁地址爲
http://maven.apache.org
。它最早的意圖只是爲了給apache組織的幾個項目提供統一的開發、測試、打包和部署,能讓開發者在多個項目中方便的切換。很多偉大的事業,出發點都很簡單,ebay就是很好的例證。而maven的成功又一次驗證了這一點,越來越多的項目開始使用maven。
基本原理
Maven的基本原理很簡單,採用遠程倉庫和本地倉庫以及一個類似build.xml的pom.xml,將pom.xml中定義的jar文件從遠程倉庫下載到本地倉庫,各個應用使用同一個本地倉庫的jar,同一個版本的jar只需下載一次,而且避免每個應用都去拷貝jar。如圖1。同時它採用了現在流行的插件體系架構,只保留最小的核心,其餘功能都通過插件的形式提供,所以maven下載很小(1.1M),在執行maven任務時,纔會自動下載需要的插件。
這個基本原理與Pear――PHP擴展與應用庫(the PHP Extension and Application Repository)的原理非常相似,都有一個官方的倉庫,都是微內核,通過網絡將需要的文件下載到本地,通過官方倉庫將相應的類庫進行統一管理。Pear已經成爲PHP開發事實上的標準,而Maven在Java世界的地位也逐漸加強,成爲標準指日可待。
另外由於插件的易開發性,現在有了非常多的可供選擇的插件,如與eclipse結合的插件,與test相關的插件,後面我們結合maven在項目中的使用進行詳細介紹。

圖1


2        項目管理


Maven官方把maven定義爲一個項目管理工具,我們不妨看看maven能給我們的項目提供哪些好的支持。
2.1       項目標準化
Maven一個重要特性是定義了項目的標準模板,官方說法是最佳實踐。可以通過命令:mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app創建一個單一的maven項目。創建好的項目,具有了特定的項目結構。這個項目結構是參考業界的最佳實踐而成,爲後面使用統一的maven命令打下了基礎,如測試mvn test、打包mvn package等,無需寫一行腳本,就可以方便的實現衆多功能。Maven還提供其它一些類型模板,可以通過添加-DarchetypeArtifactId={type}創建,如-DarchetypeArtifactId=maven-archetype-site,生成site類型的項目。
同時一些好的開源軟件使用了maven,也能作爲很好的項目模板,如Equinox(Appfuse的簡化版),它的pom定義了對hiberante,spring…的依賴,可以通過ant new -Dapp.name=NAME快速生成項目原型,然後對pom文件進行裁減,以符合自身項目的需要。
有了這個標準,項目間能方便的進行交流,你也很容易瞭解其它使用maven項目的結構。對於企業來說,引入maven就自然引入了規範,這可比費時費力的寫文檔,定規範有效的多了。
2.2       文檔和報告
使用mvn site可以快速生成項目站點,apache很多開源項目站點都採用maven生成,會出現built by maven字樣的圖標。
而maven提供的針對如junit,checkstyle,pmd等的插件,能夠方便的進行測試和檢查並能直接生成報告。使用都很簡單,如mvn surefire-report:report 就能自動進行junit測試,並生成junit報告,mvn pmd:pmd生成pmd報告。具體使用可以在
http://maven.apache.org/plugins/index.html
找到。
2.3       類庫管理
Maven一個很重要的特色就是類庫管理。通過在pom.xml中定義jar包版本和依賴,能夠方便的管理jar文件。以下是一個簡單的jar定義片斷:
<dependency>                                                                      
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate</artifactId>
      <version>3.1</version>
      <type>jar</type>
      <scope>runtime</scope>
 </dependency>

這個片斷告訴我們,依賴的jar包groupId爲org.hibernate,artifactId爲hibernate,版本爲3.1,scope爲runtime。在實際項目中,會將M2_REPO(maven本地倉庫地址)/ org/hibernate / hibernate /3.1/ hibernate -3.1.jar放入classpath。
同時maven會通過pom.xml管理jar包間的依賴。比如上面的hibernate-3.1.jar同級目錄肯定會有一個hibernate -3.1.pom,在這個pom文件中指定了這個jar對其它一些jar的依賴。而這個pom文件是遠程倉庫提供,無需進行修改,執行maven相關命令就會自動根據相關依賴去下載jar包。這樣只需定義對hibernate的依賴而無需關心相關jar,在構建項目上方便了很多。
因爲pom文件對jar的管理,也產生了一個很吸引人的特性:項目文件很小。以往一個web項目中,jar文件都要放入WEB-INF/lib下,並放入cvs(svn)中,很容易就達到幾十M。而通過maven,只需一個pom.xml,在執行mvn eclipse:eclipse時再去遠程倉庫下載,項目文件一般只需幾百K。
2.4       發佈管理
使用maven可以方便的進行項目發表管理。在項目開發到一定階段,可以使用mvn package打包,它會自動先運行mvn test,跑所有的testcase,只有全部通過才能正確打包。生成的war包(如果項目的packaging爲war)在target目錄下。這個war包與使用ant腳本生成一樣,但無需一行腳本,這也是maven對比ant的優勢之一。使用mvn install將編譯和打包好的文件發佈到distributionManager指定的遠程repository。使用mvn deploy可以自動管理項目版本。
 
3        使用maven
Maven使用簡單,插件豐富且經過大量項目考驗,在項目中引入的風險很小。筆者在項目中使用maven,新進員工在半小時內就能成功使用maven構建項目,並很快掌握幾個常用的命令。Maven也不需要什麼特殊的設施。如果項目全部使用開源軟件,並且不需要maven管理項目版本,只需要一個SCM環境(CVS或SVN),共享開發源碼就可以。把pom.xml中的repository設爲官方地址就行,配置如下:
<repository>
      <id>central</id>
      <url>http://www.ibiblio.org/maven2</url>
</repository>

這個官方remote repository上有非常多的開源軟件,應該能滿足大部分項目的需要。如果有項目需要而它上面暫時還沒有的軟件,或者希望使用公司內部的軟件,那麼就需要自己配置一個repository了。
3.1       自建私服
傳奇私服大家應該都聽過,一個網吧自己搞個私服,一夥人免費在上面砍殺。官方因此少賺了很多錢,因此總想打擊。而maven官方卻對自建私服很是支持,我們總算可以正正當當搞把私服了(Springside的老大江南白衣就是創建私服的好手)。我們就來介紹下自建私服的最快方法。
首先需要一個http server,找臺服務器裝上apache就行。放一個空的maven目錄到htdocs下,假設服務器ip爲192.168.0.1,確認能用
http://192.168.0.1/maven
訪問到。然後在自己機器上裝好maven2,初始化好項目,在pom.xml放入需要的jar定義,運行如mvn eclipse:eclipse就自動從官方下載jar到本地,如果不做配置,默認本地repository爲${user.home}/.m2/。對於windows xp來說一般在C:/Documents and Settings/%username%/.m2下,其中%username%爲操作系統登錄用戶名。這時你可以看到${user.home}/.m2/下多了個repository目錄,裏面有很多的項目相關jar,目錄按groupId/ artifactId/version排好。把repository目錄整個拷貝到apache服務器的maven目錄下,如果需要官方缺少的jar或公司內部jar,仿照這個目錄結構,做好jar放到maven目錄下。自建私服成功!
要使用私服,只需修改pom.xml,在repository配置後加上:
<repository>
      <id>companyName</id>
      <url>http:// ${ip}/maven</url>
</repository>

這樣需要下載jar時,會先到本地repository查看,沒有下載過再到官方搜索,沒有找到再到後面的repository查找。
3.2       安裝配置
Maven的安裝很簡單:
1.         從apache網站上下載maven安裝包,實際上就是個壓縮文件。將其解壓到你想要存放maven的目錄中。在這裏假設你將maven解壓到C:/Program Files/Apache Software Foundation/maven-2.0.4中。
2.      將C:/Program Files/Apache Software Foundation/maven-2.0.4/bin設到你的系統環境變量%PATH%中。
3.      同時確保你已經將你的JDK安裝目錄設爲java_home系統變量。
4.         打開個命令行窗口,運行mvn –version驗證是否安裝成功。
5.         如果使用eclipse,在運行mvn eclipse:eclipse生成eclipse項目文件後,需加入M2_REPO到Classpath Variables中,指向本地repository,例如:C:/Documents and Settings/Owner/.m2/repository。
3.3       基本使用流程
在項目進程中,不必做什麼配置,在pom.xml同級目錄,cmd使用簡單的maven命令,就可以完成初始化->開發->測試->發佈的全過程。Maven的基本使用流程如下圖:

 
 

其中在初次使用命令mvn eclipse:eclipse時會下載很多的插件和jar,可能需要較長的時間,建議泡杯咖啡,和同事吹吹牛。如果失敗,可能是網絡問題,可以重新運行mvn eclipse:eclipse,已下載好的插件和jar不會再下。運行mvn test和mvn package等命令,產出物都會放在target目錄下。如果在使用過程中有什麼問題,也可以和我聯繫,mail:[email protected],我們一起來嘗試解決。
 
總結:
Maven作爲新的項目管理工具,簡單易用,能對項目的各個階段提供大力支持,同時由於它易擴展的插件體系架構,出現了越來越多的插件,也使得其功能更加強大。短短一篇文章,實在很難把其特點一一盡述,maven還有很多好用的功能和插件等待我們去使用和開發。而學習新技術的最好方式就是實踐,大家如果有興趣,儘快下載一個最新版,開始你的maven之旅吧!
 
 
參考文檔:
1.      
http://maven.apache.org
官方網站文檔
2.      
http://www-128.ibm.com/developerworks/cn/opensource/os-maven2/
Maven2的新特性
Maven 出現到現在也有很長時間了,初識它的感覺至今仍清晰的印在腦海中。現在想來,當時從 Ant 移情 Maven 的想法其實很樸素,就是因爲 Maven 可以以網站的形式展現與項目相關的信息,如開發人員列表、各種 Report。這種方式爲項目的構建帶來了極大的方便,尤其是 Report 的。試想對於產生的 Junit-Report、JavaDoc、CheckStyle、PMD 等報告,如果沒有一個統一的入口,每次切換目錄是多麼令人厭煩的事情!

Maven 無疑是相當成功的,這一點從越來越多的開源項目開始使用 Maven 就可以看出。Maven 取得成功的原因很簡單:在簡化構建腳本的同時,功能並沒有縮水,反而有所增強;提供彙集項目信息的工具,並以相當友好的方式呈現;豐富的插件簡化了工作。如此有力的工具出現,自然是爭相使用。

新特性

如今 Maven2 已經推出,Maven 的官方網站稱,Maven2 相對於 Maven1 是一個相當大的轉變,甚至不惜犧牲兼容性來達到這一目的。(爲了 Maven1 的用戶着想,Maven1 仍在繼續他的使命。)如此大的變動到底換來了什麼樣的結果?

1. 更快、更簡單

比起 Maven1 那不急不慢的運行速度,Maven2在速度上有了質的飛躍,甚至與Ant相比也毫不遜色(當然,下載不算)。除此之外,"簡化工作,使用業界公認的最佳實踐"也是是 Maven2 的另一大主題,其他的新特性無處不在體現 Maven2 爲簡化工作而做出的努力。

2. 更少的配置文件

Maven1 和 Maven2 主要配置文件的對比:

Maven1:project.xml、maven.xml、project.properties和build.properties。
Maven2:pom.xml和settings.xml。
POM是Maven的核心對象模型,在Maven2中POM已由project.xml轉移到pom.xml中使用,版本也由3升級爲4。對於項目,一般只需要pom.xml就行了。

在Maven2中不需要也不提倡使用maven.xml,原因如下:

plugin的易用性的增強。
散佈於maven.xml中的內容難以在不同項目間共享,也不利於維護。在Maven2中建議使用自定義的plugin來封裝這些內容。
如果仍期望能夠使用類似maven.xml的功能,如<preGoal>,請參考Inserting non-standard build steps using preGoals and postGoals。

在Maven2中,配置使用settings.xml,它取代了原有的project.properties和build.properties。配置在Maven2中存在兩種級別:

用戶級,針對操作系統登錄用戶而言。一般在$home/.m2/,對於windows用戶,就是目錄:C:/Documents and Settings/用戶名/.m2/settings.xml。
全局級:一般在%M2_HOME%/conf/settings.xml,M2_HOME是Maven2的根目錄環境變量名。
在settings.xml中可以配置,如本地Repository、proxy等等,關於settings.xml的結構可以從Maven的官方網站上獲取。

3. Plugin語言更換

在Maven2中,編寫plugin的語言由jelly變更爲Java和BeanShell。Java在速度上更有優勢,而且開發人員的熟悉程度更高。對於其他的流行腳本,如groovy,Maven的官方網站的意見是,等待其更成熟時再考慮


4. 提供預定義的目錄模板

好的目錄結構可以使開發人員更容易理解項目,爲以後的維護工作也打下良好的基礎。Maven2根據業界公認的最佳目錄結構,爲開發者提供了缺省的標準目錄模板。Maven2的標準目錄結構如下:


 

使用目錄模板,可以使pom.xml更簡潔。因爲Maven2已經根據缺省目錄,預定義了相關的動作,而無需人工的干預。以resources目錄爲例:

src/main/resources,負責管理項目主體的資源。在使用Maven2執行compile之後,這個目錄中的所有文件及子目錄,會複製到target/classes目錄中,爲以後的打包提供了方便。
src/test/resources,負責管理項目測試的資源。在使用Maven2執行test-compile之後,這個目錄中的所有文件及子目錄,會複製到target/test-classes目錄中,爲後續的測試做好了準備。
這些動作在 Maven1 中,是需要在 maven.xml 中使用<preGoal>或<postGoal>來完成的。如今,完全不需要在pom.xml中指定就能夠自動完成。在src和test都使用resources,方便構建和測試,這種方式本就已是前人的經驗。通過使用Maven2,使這個經驗在開發團隊中得到普及。

創建標準目錄模板,可以通過如下命令:

 

mvn archetype:create -DgroupId=com.codeline.commons -DartifactId=codelineCommons
 


groupId和artifactId的含義與Maven1中的含義一樣,參數artifactId的值會作爲項目根目錄的名字。除了建立相應的目錄之外,Maven2還會創建缺省的pom.xml。

Maven2也考慮到:不同類型的項目需要擁有不同的目錄結構。如創建web項目,可以使用命令:

 

mvn archetype:create -DgroupId=com.mycompany.app
-DartifactId=my-webapp
-DarchetypeArtifactId=maven-archetype-webapp
 


5. 生命週期的引入

在Maven2中有了明確的生命週期概念,而且都提供與之對應的命令,使得項目構建更加清晰明瞭。主要的生命週期階段:

validate,驗證工程是否正確,所有需要的資源是否可用。
compile,編譯項目的源代碼。
test-compile,編譯項目測試代碼。
test,使用已編譯的測試代碼,測試已編譯的源代碼。
package,已發佈的格式,如jar,將已編譯的源代碼打包。
integration-test,在集成測試可以運行的環境中處理和發佈包。
verify,運行任何檢查,驗證包是否有效且達到質量標準。
install,把包安裝在本地的repository中,可以被其他工程作爲依賴來使用
deploy,在整合或者發佈環境下執行,將最終版本的包拷貝到遠程的repository,使得其他的開發者或者工程可以共享。
generate-sources,產生應用需要的任何額外的源代碼,如xdoclet。
如果要執行項目編譯,那麼直接輸入:mvn compile即可,對於其他的階段可以類推。階段之間是存在依賴關係(dependency)的,如test依賴test-compile。在執行mvn test時,會先運行mvn test-compile,然後纔是mvn test。

6. 新增Dependency Scope

在POM 4中,<dependency>中還引入了<scope>,它主要管理依賴的部署。目前<scope>可以使用5個值:

compile,缺省值,適用於所有階段,會隨着項目一起發佈。
provided,類似compile,期望JDK、容器或使用者會提供這個依賴。如servlet.jar。
runtime,只在運行時使用,如JDBC驅動,適用運行和測試階段。
test,只在測試時使用,用於編譯和運行測試代碼。不會隨項目發佈。
system,類似provided,需要顯式提供包含依賴的jar,Maven不會在Repository中查找它。
<scope>的使用舉例:

 

<dependency>
<groupId>hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
 


7. 傳遞依賴,簡化依賴管理

在Maven1中,需要把依賴所需要的包也一併列出。這對於使用類似如Hibernate的用戶來說所操的心太多了,而且也不方便。在Maven2中實現了傳遞依賴,如此對於Hibernate所依賴的包,Maven2會自動下載,開發人員只需關心Hibernate即可。

注意:只有得到Maven支持的依賴,通常是plugin形式出現,才能獲得這個特性。而且對於一些老的plugin,可能由於時間的關係不支持傳遞依賴。如至少在Maven 2.0.1中,對於Hibernate 2.1.2,仍然需要顯式列出Hibernate 2.1.2所依賴的包。

 

 

 

使用簡介

安裝Maven2的步驟非常簡單:首先從Maven官方網站下載相應的軟件包,目前是Maven 2.0.1;然後解壓,並設置環境變量M2_HOME= Maven2的解壓安裝目錄;最後將%M2_HOME%/bin添加到path中,方便Maven在任何目錄下運行。

Maven2的運行命令是mvn,使用mvn -h可以獲得相關的幫助信息。常用情形:

創建Maven項目:mvn archetype:create
編譯源代碼:mvn compile
編譯測試代碼:mvn test-compile
運行測試:mvn test
產生site:mvn site
打包:mvn package
在本地Repository中安裝jar:mvn install
清除產生的項目:mvn clean
或許是由於剛剛推出的緣故,Maven2目前還是有一些不盡如人意的地方。尤其是Report部分的plugin,有的是因爲目前還沒有,如junit-report。有的則是一些莫名其妙的問題,如checktyle和pmd,在本地locale下都無法正常工作。以pmd舉例,在產生PMD報告時會拋出如下異常:

 

java.util.MissingResourceException: Can't find bundle for base name pmd-report,
locale zh_CN
        at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle
.java:839)
        at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:808)
        at java.util.ResourceBundle.getBundle(ResourceBundle.java:702)
……
 


幸運的是,Maven2一出現就備受關注,要不了多長時間,諸如此類的問題應該就會很快解決。

 

結論

Maven2在Maven1的優勢基礎之上,又向前邁進了一大步。它提供的這些新特性大大地縮短了開發管理中的工作量,使得開發人員將精力集中在實際的業務問題上。而且這些新特性對於簡化使用,普及最佳實踐,也起到了積極的作用。



發佈了28 篇原創文章 · 獲贊 12 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章