Maven的安裝、配置及使用入門(轉載)

本書代碼下載 
你們能夠從個人網站下載本書的代碼:http://www.juvenxu.com/mvn-in-action/,也能夠經過個人網站與我取得聯繫,歡迎你們與我交流任何關於本書的問題和關於Maven的問題。 

咖啡與工具 
本書至關一部分的內容是在蘇州十全街邊的Solo咖啡館完成的,老闆Yin親手烘焙咖啡豆、並能作出聽說是蘇州最好的咖啡,這小橋流水畔的舒適小 屋可以幫我消除緊張和焦慮,和Yin有一句沒一句的聊天也是至關的輕鬆。Yin還教會了我如何本身研磨咖啡豆、手衝滴率咖啡,讓我可以天天在家裏也能享受 香氣四溢的新鮮咖啡。 
本書的書稿是使用Git和Unfuddle(http://unfuddle.com/)進行管理的,書中的大量截圖是經過Jing(http://www.techsmith.com/jing/)製做的。 
JuvenXu 
2010年10月於蘇州Solo咖啡 


致謝 
感謝費曉峯,是你最先讓我學習使用Maven,並在我開始學習的過程當中給予了很多幫助。 
感謝Maven開源社區特別是Maven的創立者Jason Van Zyl,是大家一塊兒創造瞭如此優秀的開源工具,造福了全世界這麼多的開發人員。 
感謝個人家人,一年來,個人大部分原來屬於大家的業餘時間都給了這本書,感謝大家的理解和支持。 
感謝二少、Garin、Sutra、JTux、紅人、linux_china、Chris、Jdonee、zc092二、還有不少Maven中文社區的朋友,大家給了本書很多建議,並在我寫做過程當中不斷鼓勵我和支持我,大家是我寫做最大的動力之一。 
最後感謝本書的策劃編輯楊福川和曾珊,我從大家身上學到了不少,大家是最專業的、最棒的。html

第1章 Maven簡介

1.1  何爲Maven/2java

1.2  爲何須要Maven/4linux

1.3  Maven與極限編程/7
1.4  被誤解的Maven/8
1.5  小結/9git

1.1 何爲Maven

Maven這個詞能夠翻譯爲「知識的積累」,也能夠翻譯爲「專 家」或「內行」。本書將介紹Maven這一跨平臺的項目管理工具。做爲Apache組織中的一個頗爲成功的開源項目,Maven主要服務於基於Java平 臺的項目構建、依賴管理和項目信息管理。不管是小型的開源類庫項目,仍是大型的企業級應用;不管是傳統的瀑布式開發,仍是流行的敏捷模式,Maven都能 大顯身手。程序員

1.1.1  何爲構建

無論你是否意識到,構建(build)是每一位程序員天天都在作的工做。早上來 到公司,咱們作的第一件事情就是從源碼庫簽出最新的源碼,而後進行單元測試,若是發現失敗的測試,會找相關的同事一塊兒調試,修復錯誤代碼。接着回到本身的 工做上來,編寫本身的單元測試及產品代碼,咱們會感激IDE隨時報出的編譯錯誤提示。
忙到午餐時間,代碼編寫得差很少了,測試也經過了,開心地享 用午飯,而後休息。下午先在昏昏沉沉中開了個例會,會議結束後喝杯咖啡繼續工做。剛纔在會上經理要求看測試報告,因而找了相關工具集成進IDE,生成了像 模像樣的測試覆蓋率報告,接着發了一封電子郵件給經理,鬆了口氣。誰料QA小組又發過來了幾個bug,沒辦法,先本地重現再說,因而熟練地用IDE生成了 一個WAR包,部署到Web容器下,啓動容器。看到熟悉的界面了,遵循bug報告,一步步重現了bug……快下班的時候,bug修好了,提交代碼,通知 QA小組,在愉快中結束了一天的工做。web

仔細總結一下,咱們會發現,除了編寫源代碼,咱們天天有至關一部分時間花在了編 譯、運行單元測試、生成文檔、打包和部署等煩瑣且不起眼的工做上,這就是構建。若是咱們如今還手工這樣作,那成本也過高了,因而有人用軟件的方法讓這一系 列工做徹底自動化,使得軟件的構建能夠像全自動流水線同樣,只須要一條簡單的命令,全部煩瑣的步驟都可以自動完成,很快就能獲得最終結果。spring

1.1.2  Maven是優秀的構建工具

前面介紹了Maven的用途之一是服務於構建,它是一個異常強大的構建工具,能 夠幫咱們自動化構建過程,從清理、編譯、測試到生成報告,再到打包和部署。咱們不須要也不該該一遍又一遍地輸入命令,一次又一次地點擊鼠標,咱們要作的是 使用Maven配置好項目,而後輸入簡單的命令(如mvn clean install),Maven會幫咱們處理那些煩瑣的任務。shell

Maven是跨平臺的,這意味着不管是在Windows上,仍是在Linux或者Mac上,均可以使用一樣的命令。apache

咱們一直在不停地尋找避免重複的方法。設計的重複、編碼的重複、文檔的重複,當 然還有構建的重複。Maven最大化地消除了構建的重複,抽象了構建生命週期,而且爲絕大部分的構建任務提供了已實現的插件,咱們再也不須要定義過程,甚至 不須要再去實現這些過程當中的一些任務。最簡單的例子是測試,咱們不必告訴Maven去測試,更不須要告訴Maven如何運行測試,只須要遵循Maven 的約定編寫好測試用例,當咱們運行構建的時候,這些測試便會自動運行。編程

想象一下,Maven抽象了一個完整的構建生命週期模型,這個模型吸收了大量其 他的構建腳本和構建工具的優勢,總結了大量項目的實際需求。若是遵循這個模型,能夠避免不少沒必要要的錯誤,能夠直接使用大量成熟的Maven插件來完成我 們的任務(不少時候咱們可能都不知道本身在使用Maven插件)。此外,若是有很是特殊的需求,咱們也能夠輕鬆實現本身的插件。

Maven還有一個優勢,它能幫助咱們標準化構建過程。在Maven以前,十個項目可能有十種構建方式;有了Maven以後,全部項目的構建命令都是簡單一致的,這極大地避免了沒必要要的學習成本,並且有利於促進項目團隊的標準化。

綜上所述,Maven做爲一個構建工具,不只能幫咱們自動化構建,還可以抽象構建過程,提供構建任務實現;它跨平臺,對外提供了一致的操做接口,這一切足以使它成爲優秀的、流行的構建工具。

1.1.3  Maven不只僅是構建工具

Java不只是一門編程語言,仍是一個平臺,經過JRuby和Jython,我 們能夠在Java平臺上編寫和運行Ruby和Python程序。咱們也應該認識到,Maven不只是構建工具,仍是一個依賴管理工具和項目信息管理工具。 它提供了中央倉庫,能幫咱們自動下載構件。

在這個開源的年代裏,幾乎任何Java應用都會借用一些第三方的開源類庫,這些 類庫均可經過依賴的方式引入到項目中來。隨着依賴的增多,版本不一致、版本衝突、依賴臃腫等問題都會接踵而來。手工解決這些問題是十分枯燥的,幸運的是 Maven提供了一個優秀的解決方案,它經過一個座標系統準確地定位每個構件(artifact),也就是經過一組座標Maven可以找到任何一個 Java類庫(如jar文件)。Maven給這個類庫世界引入了經緯,讓它們變得有秩序,因而咱們能夠藉助它來有序地管理依賴,輕鬆地解決那些繁雜的依賴 問題。

Maven還能幫助咱們管理本來分散在項目中各個角落的項目信息,包括項目描 述、開發者列表、版本控制系統地址、許可證、缺陷管理系統地址等。這些微小的變化看起來很瑣碎,並不起眼,但卻在不知不覺中爲咱們節省了大量尋找信息的時 間。除了直接的項目信息,經過Maven自動生成的站點,以及一些已有的插件,咱們還可以輕鬆得到項目文檔、測試報告、靜態分析報告、源碼版本日誌報告等 很是具備價值的項目信息。

Maven還爲全世界的Java開發者提供了一個免費的中央倉庫,在其中幾乎能夠找到任何的流行開源類庫。經過一些Maven的衍生工具(如Nexus),咱們還能對其進行快速地搜索。只要定位了座標,Maven就可以幫咱們自動下載,省去了手工勞動。

使用Maven還能享受一個額外的好處,即Maven對於項目目錄結構、測試用 例命名方式等內容都有既定的規則,只要遵循了這些成熟的規則,用戶在項目間切換的時候就免去了額外的學習成本,能夠說是約定優於配置 (Convention Over Configuration)。

1.2 爲何須要Maven

Maven不是Java領域惟一的構建管理的解決方案。本節將經過一些簡單的例子解釋Maven的必要性,並介紹其餘構建解決方案,如IDE、Make和Ant,並將它們與Maven進行比較。

1.2.1  組裝PC和品牌PC

筆者初中時開始接觸計算機,到了高中時更是求之不得但願擁有一臺本身的計算機。個人第一臺計算機是賽揚733的,選購是一個漫長的過程,我先閱讀了大量的雜誌以瞭解各種配件的優劣,CPU、內存、主板、顯卡,甚至聲卡,我都仔細地挑選,後來還跑了不少商家,調貨、討價還價,組裝好後本身裝操做系統和驅動程序……雖然這花費了我大量時間,但我很享受這個過程。但是事實證實,裝出來的機器穩定性不怎麼好。

一年前我須要配一臺工做站,這時候我已經沒有太多時間去研究電腦配件了。我選擇了某知名PC供應商的在線商店,大概瀏覽了一下主流的機型,選擇了我須要的配置,而後下單、付款。接着PC供應商幫我組裝電腦、安裝操做系統和驅動程序。一週後,物流公司將電腦送到個人家裏,我接上顯示器、電源、鼠標和鍵盤就能直接使用了。這爲我節省了大量時間,並且這臺電腦十分穩定,商家在把電腦發送給我以前已經進行了很好的測試。對了,我還能享受兩年的售後服務。

使用腳本創建高度自定義的構建系統就像買組裝PC,耗時費力,結果也不必定很好。固然,你能夠享受從無到有的樂趣,但恐怕實際項目中沒法給你那麼多時間。使用Maven就像購買品牌PC,省時省力,並能獲得成熟的構建系統,還能獲得來自於Maven社區的大量支持。惟一與購買品牌PC不一樣的是,Maven是開源的,你無須爲此付費。若是有興趣,你還能去了解Maven是如何工做的,而咱們沒法知道那些PC巨頭的商業祕密。

1.2.2  IDE不是萬能的

固然,咱們沒法否定優秀的IDE能大大提升開發效率。當前主流的IDE如Eclipse和NetBeans等都提供了強大的文本編輯、調試甚至重構功能。雖然使用簡單的文本編輯器和命令行也能完成絕大部分開發工做,但不多有人願意那樣作。然而,IDE是有其天生缺陷的:

  • IDE依賴大量的手工操做。編譯、測試、代碼生成等工做都是相互獨立的,很難一鍵完成全部工做。手工勞動每每意味着低效,意味着容易出錯。
  • 很難在項目中統一全部的IDE配置,每一個人都有本身的喜愛。也正是因爲這個緣由,一個在機器A上能夠成功運行的任務,到了機器B的IDE中可能就會失敗。

咱們應該合理利用IDE,而不是過多地依賴它。對於構建這樣的任務,在IDE中一次次地點擊鼠標是愚蠢的行爲。Maven是這方面的專家,並且主流IDE都集成了Maven,咱們能夠在IDE中方便地運行Maven執行構建。

1.2.3  Make

Make也許是最先的構建工具,它由Stuart Feldman於1977年在Bell實驗室建立。Stuart Feldman也所以於2003年得到了ACM國際計算機組織頒發的軟件系統獎。目前Make有不少衍生實現,包括最流行的GNU Make和BSD Make,還有Windows平臺的Microsoft nmake等。

Make由一個名爲Makefile的腳本文件驅動,該文件使用Make本身定義的語法格式。其基本組成部分爲一系列規則(Rules),而每一條規則又包括目標(Target)、依賴(Prerequisite)和命令(Command)。Makefile的基本結構以下:

  1. <span style="font-size: small;">TARGET… : PREREQUISITE…  
  2. COMMAND  
  3. …  
  4. …  
  5. </span>  

     Make經過一系列目標和依賴將整個構建過程串聯起來,同時利用本地命令完成每一個目標的實際行爲。Make的強大之處在於它能夠利用全部系統的本地命令,尤爲是UNIX/Linux系統,豐富的功能、強大的命令可以幫助Make快速高效地完成任務。

可是,Make將本身和操做系統綁定在一塊兒了。也就是說,使用Make,就不能實現(至少很難)跨平臺的構建,這對於Java來講是很是不友好的。此外,Makefile的語法也成問題,不少人抱怨Make構建失敗的緣由每每是一個難以發現的空格或Tab使用錯誤。

1.2.4  Ant

Ant不是指螞蟻,而是意指「另外一個整潔的工具」(Another Neat Tool),它最先用來構建著名的Tomcat,其做者James Duncan Davidson創做它的動機就是由於受不了Makefile的語法格式。咱們能夠將Ant當作是一個Java版本的Make,也正由於使用了Java,Ant是跨平臺的。此外,Ant使用XML定義構建腳本,相對於Makefile來講,這也更加友好。

與Make相似,Ant有一個構建腳本build.xml,以下所示:

<?xml version="1.0"?>

<project name="Hello" default="compile">

<target name="compile" description="compile the Java source code to class files">

<mkdir dir="classes"/>

<javac srcdir="." destdir="classes"/>

</target>

<target name="jar" depends="compile" description="create a Jar file ">

<jar destfile="hello.jar">

<fileset dir="classes" includes="**/*.class"/>

<manifest>

<attribute name="Main.Class" value="HelloProgram"/>

</manifest>

</jar>

</target>

</project>

build.xml的基本結構也是目標(target)、依賴(depends),以及實現目標的任務。好比在上面的腳本中,jar目標用來建立應用程序jar文件,該目標依賴於compile目標,後者執行的任務是建立一個名爲classes的文件夾,編譯當前目錄的java文件至classes目錄。compile目標完成後,jar目標再執行本身的任務。Ant有大量內置的用Java實現的任務,這保證了其跨平臺的特質,同時,Ant也有特殊的任務exec來執行本地命令。

和Make同樣,Ant也都是過程式的,開發者顯式地指定每個目標,以及完成該目標所須要執行的任務。針對每個項目,開發者都須要從新編寫這一過程,這裏其實隱含着很大的重複。Maven是聲明式的,項目構建過程和過程各個階段所需的工做都由插件實現,而且大部分插件都是現成的,開發者只須要聲明項目的基本元素,Maven就執行內置的、完整的構建過程。這在很大程度上消除了重複。

Ant是沒有依賴管理的,因此很長一段時間Ant用戶都不得不手工管理依賴,這是一個使人頭疼的問題。幸運的是,Ant用戶如今能夠藉助Ivy管理依賴。而對於Maven用戶來講,依賴管理是理所固然的,Maven不只內置了依賴管理,更有一個可能擁有全世界最多Java開源軟件包的中央倉庫,Maven用戶無須進行任何配置就能夠直接享用。

1.2.5  不重複發明輪子

【該小節內容整理自網友Arthas最先在Maven中文MSN的羣內的討論,在此表示感謝】

小張是一家小型民營軟件公司的程序員,他所在的公司要開發一個新的Web項目。通過協商,決定使用Spring、iBatis和Tapstry。jar包去哪裏找呢?公司裏估計沒有人能把Spring、iBatis和Tapstry所使用的jar包一個很多地找出來。你們的作法是,先到Spring的站點上去找一個spring.with.dependencies,而後去iBatis的網站上把全部列出來的jar包下載下來,對Tapstry、Apache commons等執行一樣的操做。項目尚未開始,WEB.INF/lib下已經有近百個jar包了,帶版本號的、不帶版本號的、有用的、沒用的、相沖突的,怎一個「亂」字了得!

在項目開發過程當中,小張不時地發現版本錯誤和版本衝突問題,他只能硬着頭皮逐一解決。項目開發到一半,經理髮現最終部署的應用的體積實在太大了,要求小張去掉一些沒用的jar包,因而小張只能加班加點地一個個刪……

小張隱隱地以爲這些依賴須要一個框架或者系統來進行管理。

小張喜歡學習流行的技術,前幾年Ant十分流行,他學了,併成爲了公司這方面的專家。小張知道,Ant打包,無非就是建立目錄,複製文件,編譯源代碼,使用一堆任務,如copydir、fileset、classpath、ref、target,而後再jar、zip、war,打包就成功了。

項目經理髮話了:「兄弟們,新項目來了,小張,你來寫Ant腳本!」

「是,保證完成任務!」接着,小張繼續建立一個新的XML文件。target clean; target compile; target jar; …… 不知道他是否想過,在他寫的這麼多的Ant腳本中,有多少是重複勞動,有多少代碼會在一個又一個項目中重現。既然都差很少,有些甚至徹底相同,爲何每次都要從新編寫?

終於有一天,小張意識到了這個問題,想複用Ant腳本,因而在開會時他說:「之後就都用我這個規範的Ant腳本吧,新的項目只要遵循我定義的目錄結構就能夠了。」經理聽後以爲頗有道理:「嗯,確實是個進步。」

這時新來的研究生髮言了:「經理,用Maven吧,這個在開源社區很流行,比Ant更方便。」小張一聽很驚訝,Maven真比本身的「規範化Ant」強大?其實他不知道本身只是在從新發明輪子,Maven已經有一大把現成的插件,全世界都在用,你本身不用寫任何代碼!

爲何沒有人說「我本身寫的代碼最靈活,因此我不用Spring,我本身實現IoC;我不用Hibernate,我本身封裝JDBC」?

1.3 Maven與極限編程

極限編程(XP)是近些年在軟件行業紅得發紫的敏捷開發方法,它強調擁抱變化。該軟件開發方法的創始人Kent Beck提出了XP所追求的價值、實施原則和推薦實踐。下面看一下Maven是如何適應XP的。
首先看一下Maven如何幫助XP團隊實現一些核心價值:

  • 簡單。Maven暴露了一組一致、簡潔的操做接口,能幫助團隊成員從原來的高度自定義的、複雜的構建系統中解脫出來,使用Maven現有的成熟的、穩定的組件也能簡化構建系統的複雜度。
  • 交流與反饋。與版本控制系統結合後,全部人都能執行最新的構建並快速獲得反饋。此外,自動生成的項目報告也能幫助成員瞭解項目的狀態,促進團隊的交流。

此外,Maven更能無縫地支持或者融入到一些主要的XP實踐中:

  • 測試驅動開發(TDD)。TDD強調測試先行,全部產品都應該由測試用例覆蓋。而測試是Maven生命週期的最重要的組成部分之一,而且Maven有現成的成熟插件支持業界流行的測試框架,如JUnit和TestNG。
  • 十分鐘構建。十分鐘構建強調咱們可以隨時快速地從源碼構建出最終的產品。這正是Maven所擅長的,只須要一些配置,以後用一條簡單的命令就能讓Maven幫你清理、編譯、測試、打包、部署,而後獲得最終的產品。
  • 持續集成(CI)。CI強調項目以很短的週期(如15分鐘)集成最新的代碼。 實際上,CI的前提是源碼管理系統和構建系統。目前業界流行的CI服務器如Hudson和CruiseControl都能很好地和Maven進行集成。也 就是說,使用Maven後,持續集成會變得更加方便。
  • 富有信息的工做區。 這條實踐強調開發者可以快速方便地瞭解到項目的最新狀態。固然,Maven並不會幫你把測試覆蓋率報告貼到牆上,也不會在你的工做臺上放個鴨子告訴你構建 失敗了。不過使用Maven發佈的項目報告站點,並配置你須要的項目報告,如測試覆蓋率報告,都能幫你把信息推送到開發者眼前。

上述這些實踐並不是只在XP中適用。事實上,除了其餘敏捷開發方法如SCRUM以外,幾乎任何軟件開發方法都能借鑑這些實踐。也就是說,Maven幾乎可以很好地支持任何軟件開發方法。
例 如,在傳統的瀑布模型開發中,項目依次要經歷需求開發、分析、設計、編碼、測試和集成發佈階段。從設計和編碼階段開始,就能夠使用Maven來創建項目的 構建系統。在設計階段,也徹底能夠針對設計開發測試用例,而後再編寫代碼來知足這些測試用例。然而,有了自動化構建系統,咱們能夠節省不少手動的測試時 間。此外,儘早地使用構建系統集成團隊的代碼,對項目也是百利而無一害。最後,Maven還能幫助咱們快速地發佈項目。

第2章 Maven的安裝和配置

第1章介紹了Maven是什麼,以及爲何要使用Maven, 咱們將從本章實際開始實際接觸Maven。本章首先將介紹如何在主流的操做系統下安裝Maven,並詳細解釋Maven的安裝文件;其次還會介紹如何在主 流的IDE中集成Maven,以及Maven安裝的最佳實踐。
2.1 在Windows上安裝Maven
2.2 在基於Unix的系統上安裝Maven
2.3 安裝目錄分析
2.4 設置HTTP代理
2.5 安裝m2eclipse
2.6 安裝NetBeans Maven插件
2.7 Maven安裝最佳實踐
2.8 小結

2.1 在Windows上安裝Maven

2.1.1 檢查JDK安裝

在安裝Maven以前,首先要確認你已經正確安裝了JDK。Maven能夠運行在JDK 1.4及以上的版本上。本書的全部樣例都基於JDK 5及以上版本。打開Windows的命令行,運行以下的命令來檢查你的Java安裝:

C:\Users\Juven Xu>echo %JAVA_HOME%

C:\Users\Juven Xu>java -version

結果如圖2-1所示:

 



 圖2-1 Windows中檢查Java安裝

上述命令首先檢查環境變量JAVA_HOME是否指向了正確的JDK目錄,接着嘗試運行java命令。若是Windows沒法執行java命令,或者沒法找到JAVA_HOME環境變量。你就須要檢查Java是否安裝了,或者環境變量是否設置正確。關於環境變量的設置,請參考2.1.3節。

2.1.2 下載Maven

請訪問Maven的下載頁面:http://maven.apache.org/download.html,其中包含針對不一樣平臺的各類版本的Maven下載文件。對於首次接觸Maven的讀者來講,推薦使用Maven 3.0,,所以下載apache-maven-3.0-bin.zip。固然,若是你對Maven的源代碼感興趣並想本身構建Maven,還能夠下載apache-maven-3.0 -src.zip。該下載頁面還提供了md5校驗和(checksum)文件和asc數字簽名文件,能夠用來檢驗Maven分發包的正確性和安全性。

在本書編寫的時候,Maven 2的最新版本是2.2.1,Maven 3基本徹底兼容Maven 2,並且較之於Maven 2它性能更好,還有很多功能的改進,若是你以前一直使用Maven 2,如今正猶豫是否要升級,那就大可沒必要擔憂了,快點嘗試下Maven 3吧! 

2.1.3 本地安裝

將安裝文件解壓到你指定的目錄中,如:

D:\bin>jar xvf "C:\Users\Juven Xu\Downloads\apache-maven-3.0--bin.zip"

這裏的Maven安裝目錄是D:\bin\apache-maven-3.0,接着須要設置環境變量,將Maven安裝配置到操做系統環境中。

打開系統屬性面板(桌面上右鍵單擊「個人電腦」→「屬性」),點擊高級系統設置,再點擊環境變量,在系統變量中新建一個變量,變量名爲M2_HOME,變量值爲Maven的安裝目錄D:\bin\apache-maven-3.0。點擊肯定,接着在系統變量中找到一個名爲Path的變量,在變量值的末尾加上%M2_HOME%\bin;,注意多個值之間須要有分號隔開,而後點擊肯定。至此,環境變量設置完成,詳細狀況如圖2-2所示:

 

圖2-2 Windows中系統環境變量配置

這裏須要提一下的是Path環境變量,當咱們在cmd中輸入命令時,Windows首先會在當前目錄中尋找可執行文件或腳本,若是沒有找到,Windows會接着遍歷環境變量Path中定義的路徑。因爲咱們將%M2_HOME%\bin添加到了Path中,而這裏%M2_HOME%其實是引用了咱們前面定義的另外一個變量,其值是Maven的安裝目錄。所以,Windows會在執行命令時搜索目錄D:\bin\apache-maven-3.0\bin,而mvn執行腳本的位置就是這裏。

明白了環境變量的做用,如今打開一個新的cmd窗口(這裏強調新的窗口是由於新的環境變量配置須要新的cmd窗口才能生效),運行以下命令檢查Maven的安裝狀況:

C:\Users\Juven Xu>echo %M2_HOME%

C:\Users\Juven Xu>mvn -v

運行結果如圖2-3所示:


 圖2-3 Windows中檢查Maven安裝

第一條命令echo %M2_HOME%用來檢查環境變量M2_HOME是否指向了正確的Maven安裝目錄;而mvn –version執行了第一條Maven命令,以檢查Windows是否可以找到正確的mvn執行腳本。

2.1.4 升級Maven

Maven還比較年輕,更新比較頻繁,所以用戶每每會須要更新Maven安裝以得到更多更酷的新特性,以及避免一些舊的bug。

在Windows上更新Maven很是簡便,只須要下載新的Maven安裝文件,解壓至本地目錄,而後更新M2_HOME環境變量即可。例如,假設Maven推出了新版本3.1,咱們將其下載而後解壓至目錄D:\bin\apache-maven-3.1,接着遵守前一節描述的步驟編輯環境變量M2_HOME,更改其值爲D:\bin\apache-maven-3.1。至此,更新就完成了。同理,若是你須要使用某一箇舊版本的Maven,也只須要編輯M2_HOME環境變量指向舊版本的安裝目錄。

2.2 在基於Unix的系統上安裝Maven

Maven是跨平臺的,它能夠在任何一種主流的操做系統上運行,本節將介紹如何在基於Unix的系統(包括Linux、Mac OS以及FreeBSD等)上安裝Maven。

2.2.1 下載和安裝

首先,與在Windows上安裝Maven同樣,須要檢查JAVA_HOME環境變量以及Java命令,細節再也不贅述,命令以下:

juven@juven-ubuntu:~$ echo $JAVA_HOME

juven@juven-ubuntu:~$ java –version

運行結果如圖2-4所示:

 

圖2-4 Linux中檢查Java安裝

接着到http://maven.apache.org/download.html下載Maven安裝文件,如apache-maven-3.0-bin.tar.gz,而後解壓到本地目錄:

juven@juven-ubuntu:bin$ tar -xvzf apache-maven-3.0-bin.tar.gz

如今已經建立好了一個Maven安裝目錄apache-maven-3.0,雖然直接使用該目錄配置環境變量以後就能使用Maven了,但這裏我更推薦作法是,在安裝目錄旁平行地建立一個符號連接,以方便往後的升級:

juven@juven-ubuntu:bin$ ln -s apache-maven-3.0 apache-maven
juven@juven-ubuntu:bin$ ls -l
total 4
lrwxrwxrwx 1 juven juven   18 2009-09-20 15:43 apache-maven -> apache-maven-3.0
drwxr-xr-x 6 juven juven 4096 2009-09-20 15:39 apache-maven-3.0

接下來,咱們須要設置M2_HOME環境變量指向符號連接apache-maven-,而且把Maven安裝目錄下的bin/文件夾添加到系統環境變量PATH中去:

juven@juven-ubuntu:bin$ export M2_HOME=/home/juven/bin/apache-maven
juven@juven-ubuntu:bin$ export PATH=$PATH:$M2_HOME/bin

通常來講,須要將這兩行命令加入到系統的登陸shell腳本中去,以我如今的Ubuntu 8.10爲例,編輯~/.bashrc文件,添加這兩行命令。這樣,每次啓動一個終端,這些配置就能自動執行。

至此,安裝完成,咱們能夠運行如下命令檢查Maven安裝:

juven@juven-ubuntu:bin$ echo $M2_HOME

juven@juven-ubuntu:bin$ mvn –version

運行結果如圖2-5所示:

 圖2-5 Linux中檢查Maven安裝

2.2.2 升級Maven

在基於Unix的系統上,能夠利用符號連接這一工具來簡化Maven的升級,沒必要像在Windows上那樣,每次升級都必須更新環境變量。

前一小節中咱們提到,解壓Maven安裝包到本地以後,平行地建立一個符號連接,而後在配置環境變量時引用該符號連接,這樣作是爲了方便升級。如今,假設咱們須要升級到新的Maven 3.1版本,同理,將安裝包解壓到與前一版本平行的目錄下,而後更新符號連接指向3.1版的目錄即可:

juven@juven-ubuntu:bin$ rm apache-maven
juven@juven-ubuntu:bin$ ln -s apache-maven-3.1/ apache-maven
juven@juven-ubuntu:bin$ ls -l
total 8
lrwxrwxrwx 1 juven juven   17 2009-09-20 16:13 apache-maven -> apache-maven-3.1 /
drwxr-xr-x 6 juven juven 4096 2009-09-20 15:39 apache-maven-3.0drwxr-xr-x 2 juven juven 4096 2009-09-20 16:09 apache-maven-3.1

同理,能夠很方便地切換到Maven的任意一個版本。如今升級完成了,能夠運行mvn -v進行檢查。

2.3 安裝目錄分析

本章前面的內容講述瞭如何在各類操做系統中安裝和升級Maven。如今咱們來仔細分析一下Maven的安裝文件。

2.3.1 M2_HOME

前面咱們講到設置M2_HOME環境變量指向Maven的安裝目錄,本書以後全部使用M2_HOME的地方都指代了該安裝目錄,讓咱們看一下該目錄的結構和內容:

bin
boot
conf
lib
LICENSE.txt
NOTICE.txt
README.txt

  •  Bin: 該目錄包含了mvn運行的腳本,這些腳本用來配置Java命令,準備好classpath和相關的Java系統屬性,而後執行Java命令。其中mvn是基於UNIX平臺的shell腳本,mvn.bat是基於Windows平臺的bat腳本。在命令行輸入任何一條mvn命令時,實際上就是在調用這些腳本。該目錄還包含了mvnDebugmvnDebug.bat兩個文件,一樣,前者是UNIX平臺的shell腳本,後者是windows的bat腳本。那麼mvn和mvnDebug有什麼區別和關係呢?打開文件咱們就能夠看到,二者基本是同樣的,只是mvnDebug多了一條MAVEN_DEBUG_OPTS配置,做用就是在運行Maven時開啓debug,以便調試Maven自己。此外,該目錄還包含m2.conf文件,這是classworlds的配置文件,稍微會介紹classworlds。
  • Boot: 該目錄只包含一個文件,以maven 3.0爲例,該文件爲plexus-classworlds-2.2.3.jar。plexus-classworlds是一個類加載器框架,相對於默認的java類加載器,它提供了更豐富的語法以方便配置,Maven使用該框架加載本身的類庫。更多關於classworlds的信息請參考http://classworlds.codehaus.org/。對於通常的Maven用戶來講,沒必要關心該文件。
  • Conf: 該目錄包含了一個很是重要的文件settings.xml。直接修改該文件,就能在機器上全局地定製Maven的行爲。通常狀況下,咱們更偏向於複製該文件至~/.m2/目錄下(這裏~表示用戶目錄),而後修改該文件,在用戶範圍定製Maven的行爲。本書的後面將會屢次提到該settings.xml,並逐步分析其中的各個元素。 
  • Lib: 該目錄包含了全部Maven運行時須要的Java類庫,Maven自己是分模塊開發的,所以用戶能看到諸如mavn-core-3.0.jar、maven-model-3.0.jar之類的文件,此外這裏還包含一些Maven用到的第三方依賴如common-cli-1.2.jar、google-collection-1.0.jar等等。(對於Maven 2來講,該目錄只包含一個如maven-2.2.1-uber.jar的文件本來各爲獨立JAR文件的Maven模塊和第三方類庫都被拆解後從新合併到了這個JAR文件中)。能夠說,這個lib目錄就是真正的Maven。關於該文件,還有一點值得一提的是,用戶能夠在這個目錄中找到Maven內置的超級POM,這一點在8.5小節詳細解釋。其餘: LICENSE.txt記錄了Maven使用的軟件許可證Apache License Version 2.0; NOTICE.txt記錄了Maven包含的第三方軟件;而README.txt則包含了Maven的簡要介紹,包括安裝需求及如何安裝的簡要指令等等。 

 

2.3.2 ~/.m2

在講述該小節以前,咱們先運行一條簡單的命令:mvn help:system。該命令會打印出全部的Java系統屬性和環境變量,這些信息對咱們平常的編程工做頗有幫助。這裏暫不解釋help:system涉及的語法,運行這條命令的目的是爲了讓Maven執行一個真正的任務。咱們能夠從命令行輸出看到Maven會下載maven-help-plugin,包括pom文件和jar文件。這些文件都被下載到了Maven本地倉庫中。

如今打開用戶目錄,好比當前的用戶目錄是C:\Users\Juven Xu\,你能夠在Vista和Windows7中找到相似的用戶目錄。若是是更早版本的Windows,該目錄應該相似於C:\Document and Settings\Juven Xu\。在基於Unix的系統上,直接輸入cd 回車,就能夠轉到用戶目錄。爲了方便,本書統一使用符號 指代用戶目錄。

在用戶目錄下,咱們能夠發現.m2文件夾。默認狀況下,該文件夾下放置了Maven本地倉庫.m2/repository。全部的Maven構件(artifact)都被存儲到該倉庫中,以方便重用。咱們能夠到~/.m2/repository/org/apache/maven/plugins/maven-help-plugins/目錄下找到剛纔下載的maven-help-plugin的pom文件和jar文件。Maven根據一套規則來肯定任何一個構件在倉庫中的位置,這一點本書第6章將會詳細闡述。因爲Maven倉庫是經過簡單文件系統透明地展現給Maven用戶的,有些時候能夠繞過Maven直接查看或修改倉庫文件,在遇到疑難問題時,這每每十分有用。

默認狀況下,~/.m2目錄下除了repository倉庫以外就沒有其餘目錄和文件了,不過大多數Maven用戶須要複製M2_HOME/conf/settings.xml文件到~/.m2/settings.xml。這是一條最佳實踐,咱們將在本章最後一小節詳細解釋。

2.4 設置HTTP代理

有時候你所在的公司因爲安全因素考慮,要求你使用經過安全認證的代理訪問因特網。這種狀況下,就須要爲Maven配置HTTP代理,才能讓它正常訪問外部倉庫,如下載所須要的資源。

首先確認本身沒法直接訪問公共的Maven中央倉庫,直接運行命令ping repo1.maven.org能夠檢查網絡。若是真的須要代理,先檢查一下代理服務器是否暢通,好比如今有一個IP地址爲218.14.227.197,端口爲3128的代理服務,咱們能夠運行telnet 218.14.227.197 3128來檢測該地址的該端口是否暢通。若是獲得出錯信息,須要先獲取正確的代理服務信息;若是telnet鏈接正確,則輸入ctrl+],而後q,回車,退出便可。

檢查完畢以後,編輯~/.m2/settings.xml文件(若是沒有該文件,則複製$M2_HOME/conf/settings.xml)。添加代理配置以下:

<settings>
…  
<proxies>

    <proxy>

      <id>my-proxy</id>

      <active>true</active>

      <protocol>http</protocol>

      <host>218.14.227.197</host>

      <port>3128</port>

      <!--

      <username>***</username>

      <password>***</password>

      <nonProxyHosts>repository.mycom.com|*.google.com</nonProxyHosts>

      -->

    </proxy>

  </proxies>
  …
</settings>

這段配置十分簡單,proxies下能夠有多個proxy元素,若是你聲明瞭多個proxy元素,則默認狀況下第一個被激活的proxy會生效。這裏聲明瞭一個id爲my-proxy的代理,active的值爲true表示激活該代理,protocol表示使用的代理協議,這裏是http。固然,最重要的是指定正確的主機名(host元素)和端口(port元素)。上述XML配置中我註釋掉了username、password、nonProxyHost幾個元素,當你的代理服務須要認證時,就須要配置username和password。nonProxyHost元素用來指定哪些主機名不須要代理,能夠使用 | 符號來分隔多個主機名。此外,該配置也支持通配符,如*.google.com表示全部以google.com結尾的域名訪問都不要經過代理。

2.5 安裝m2eclipse

Eclipse是一款很是優秀的IDE。除了基本的語法標亮、代碼補齊、XML編輯等基本功能外,最新版的Eclipse還能很好地支持重構,而且集成了JUnit、CVS、Mylyn等各類流行工具。惋惜Eclipse默認沒有集成對Maven的支持。幸運的是,由Maven之父Jason Van Zyl創立的Sonatype公司創建了m2eclipse項目,這是Eclipse下的一款十分強大的Maven插件,能夠訪問http://m2eclipse.sonatype.org/ 瞭解更多該項目的信息。

本小節將先介紹如何安裝m2eclipse插件,本書後續的章節會逐步介紹m2eclipse插件的使用。

如今我以Eclipse 3.6爲例逐步講解m2eclipse的安裝。啓動Eclipse以後,在菜單欄中選擇Help,而後選擇Install New Software…,接着你會看到一個Install對話框,點擊Work with:字段邊上的Add按鈕,你會獲得一個新的Add Repository對話框,在Name字段中輸入m2e,Location字段中輸入http://m2eclipse.sonatype.org/sites/m2e,而後點擊OK。Eclipse會下載m2eclipse安裝站點上的資源信息。等待資源載入完成以後,咱們再將其所有展開,就能看到圖2-6所示的界面:

 



 圖2-6  m2eclipse的核心安裝資源列表

 

如圖顯示了m2eclipse的核心模塊Maven Integration for Eclipse (Required),選擇後點擊Next >,Eclipse會自動計算模塊間依賴,而後給出一個將被安裝的模塊列表,確認無誤後,繼續點擊Next >,這時咱們會看到許可證信息,m2eclipse使用的開源許可證是Eclipse Public License v1.0,選擇I accept the terms of the license agreements,而後點擊Finish,接着就耐心等待Eclipse下載安裝這些模塊,如圖2-7所示:

 



 圖2-7:m2eclipse安裝進度

除了核心組件以外,m2eclipse還提供了一組額外組件,主要是爲了方便與其它工具如Subversion進行集成,這些組件的安裝地址爲http://m2eclipse.sonatype.org/sites/m2e-extras。使用前面相似的安裝方法,咱們能夠看到如圖2-8的組件列表:

 



 圖2-8:m2eclipse的額外組件安裝資源列表

下面簡單解釋一下這些組件的用途:

  1. 1. 重要的
  2. 2. 不重要的
  •  Maven SCM handler for Subclipse  (Optional):Subversion是很是流行的版本管理工具,該模塊可以幫助咱們直接從Subversion服務器簽出Maven項目,不過前提是須要首先安裝Subclipse(http://subclipse.tigris.org/)。
  •  Maven SCM Integration (Optional):Eclipse環境中Maven與SCM集成核心的模塊,它利用各類SCM工具如SVN實現Maven項目的簽出和具體化等操做。
  •  Maven issue tracking configurator for Mylyn 3.x (Optional):該模塊可以幫助咱們使用POM中的缺陷跟蹤系統信息鏈接Mylyn至服務器。
  •  Maven SCM handler for Team/CVS (Optional):該模塊幫助咱們從CVS服務器簽出Maven項目,若是你還在使用CVS,就須要安裝它。
  •  Maven Integration for WTP (Optional):使用該模塊可讓Eclipse自動讀取POM信息並配置WTP項目。、
  •  M2eclipse Extensions Development Support (Optional):用來支持擴展m2eclipse,通常用戶不會用到。
  •  Project configurators for commonly used maven plugins (temporary):一個臨時的組件,用來支持一些Maven插件與Eclipse的集成,建議安裝。

讀者能夠根據本身的須要安裝相應組件,具體步驟再也不贅述。

待安裝完畢後,重啓Eclipse,如今讓咱們驗證一下m2eclipse是否正確安裝了。首先,點擊菜單欄中的Help,而後選擇About Eclipse,在彈出的對話框中,點擊Installation Details按鈕,會獲得一個對話框,在Installed Software標籤欄中,檢查剛纔咱們選擇的模塊是否在這個列表中,如圖2-9所示:

 



 圖2-9m2eclipse安裝結果

若是一切沒問題,咱們再檢查一下Eclipse如今是否已經支持建立Maven項目,依次點擊菜單欄中的FileNewOther,在彈出的對話框中,找到Maven一項,再將其展開,你應該可以看到如圖2-10所示的對話框:

 



 圖2-10 Eclipse中建立Maven項目嚮導

若是一切正常,說明m2eclipse已經正確安裝了。

最後,關於m2eclipse的安裝,須要提醒的一點是,你可能會在使用m2eclipse時遇到相似這樣的錯誤:

09-10-6 上午01時14分49秒: Eclipse is running in a JRE, but a JDK is required
Some Maven plugins may not work when importing projects or updating source folders.

這是由於Eclipse默認是運行在JRE上的,而m2eclipse的一些功能要求使用JDK,解決方法是配置Eclipse安裝目錄的eclipse.ini文件,添加vm配置指向JDK,如:

--launcher.XXMaxPermSize

256m

-vm

D:\java\jdk1.6.0_07\bin\javaw.exe

-vmargs

-Dosgi.requiredJavaVersion=1.5

-Xms128m

-Xmx256m

2.6 安裝NetBeans Maven插件

本小節會先介紹如何在NetBeans上安裝Maven插件,後面的章節中還會介紹NetBeans中具體的Maven操做。

首先,若是你正在使用NetBeans 6.7及以上版本,那麼Maven插件已經預裝了。你能夠檢查Maven插件安裝,點擊菜單欄中的工具,接着選擇插件,在彈出的插件對話框中選擇已安裝標籤,你應該可以看到Maven插件,如圖2-11所示:

 



 圖2-11 已安裝的NetBeans Maven插件

若是你在使用NetBeans 6.7以前的版本,或者因爲某些緣由NetBeans Maven插件被卸載了,那麼你就須要安裝NetBeans Maven插件,下面咱們以NetBeans 6.1爲例,介紹Maven插件的安裝。

一樣,點擊菜單欄中的工具,選擇插件,在彈出的插件對話框中選擇可用插件標籤,接着在右邊的搜索框內輸入Maven,這時你會在左邊的列表中看到一個名爲Maven的插件,選擇該插件,而後點擊下面的安裝按鈕,如圖2-12所示:

 

圖2-12 安裝NetBeans Maven插件

接着在隨後的對話框中根據提示操做,閱讀相關許可證並接受,NetBeans會自動幫咱們下載並安裝Maven插件,結束以後會提示安裝完成,以後再點擊插件對話框的已安裝標籤,就能看到已經激活的Maven插件。

 

最後,爲了確認Maven插件確實已經正確安裝了,能夠看一下NetBeans是否已經擁有建立Maven項目的相關菜單。在菜單欄中選擇文件,而後選擇新建項目,這時應該可以看到項目類別中有Maven一項,選擇該類別,右邊會相應地顯示Maven項目基於現有POM的Maven項目,如圖2-13所示:


 圖2-13 NetBeans中建立Maven項目嚮導

若是你能看到相似的對話框,說明NetBeans Maven已經正確安裝了。

2.7 Maven安裝最佳實踐

本節介紹一些在安裝Maven過程當中不是必須的,但十分有用的實踐。

2.7.1 設置MAVEN_OPTS環境變量

本章前面介紹Maven安裝目錄時咱們瞭解到,運行mvn命令其實是執行了Java命令,既然是運行Java,那麼運行Java命令可用的參數固然也應該在運行mvn命令時可用。這個時候,MAVEN_OPTS環境變量就能派上用場。

咱們一般須要設置MAVEN_OPTS的值爲:-Xms128m -Xmx512m,由於Java默認的最大可用內存每每不可以知足Maven運行的須要,好比在項目較大時,使用Maven生成項目站點須要佔用大量的內存,若是沒有該配置,咱們很容易獲得java.lang.OutOfMemeoryError。所以,一開始就配置該變量是推薦的作法。

關於如何設置環境變量,請參考前面設置M2_HOME環境變量的作法,儘可能不要直接修改mvn.bat或者mvn這兩個Maven執行腳本文件。由於若是修改了腳本文件,升級Maven時你就不得再也不次修改,一來麻煩,二來容易忘記。同理,咱們應該儘量地不去修改任何Maven安裝目錄下的文件。

2.7.2 配置用戶範圍settings.xml

Maven用戶能夠選擇配置$M2_HOME/conf/settings.xml或者~/.m2/settings.xml。前者是全局範圍的,整臺機器上的全部用戶都會直接受到該配置的影響,然後者是用戶範圍的,只有當前用戶纔會受到該配置的影響。

咱們推薦使用用戶範圍的settings.xml,主要緣由是爲了不無心識地影響到系統中的其餘用戶。固然,若是你有切實的需求,須要統一系統中全部用戶的settings.xml配置,固然應該使用全局範圍的settings.xml。

除了影響範圍這一因素,配置用戶範圍settings.xml文件還便於Maven升級。直接修改conf目錄下的settings.xml會致使Maven升級不便,每次升級到新版本的Maven,都須要複製settings.xml文件,若是使用~/.m2目錄下的settings.xml,就不會影響到Maven安裝文件,升級時就不須要觸動settings.xml文件。

2.7.3 不要使用IDE內嵌的Maven

不管是Eclipse仍是NetBeans,當咱們集成Maven時,都會安裝上一個內嵌的Maven,這個內嵌的Maven一般會比較新,但不必定很穩定,並且每每也會和咱們在命令行使用的Maven不是同一個版本。這裏有會出現兩個潛在的問題:首先,較新版本的Maven存在不少不穩定因素,容易形成一些難以理解的問題;其次,除了IDE,咱們也常常還會使用命令行的Maven,若是版本不一致,容易形成構建行爲的不一致,這是咱們所不但願看到的。所以,咱們應該在IDE中配置Maven插件時使用與命令行一致的Maven。

在m2eclipse環境中,點擊菜單欄中的Windows,而後選擇Preferences,在彈出的對話框中,展開左邊的Maven項,選擇Installation子項,在右邊的面板中,咱們可以看到有一個默認的Embedded Maven安裝被選中了,點擊Add…而後選擇咱們的Maven安裝目錄M2_HOME,添加完畢以後選擇這一個外部的Maven,如圖2-14所示:

 



 圖2-14 在Eclipse中使用外部Maven

NetBeans Maven插件默認會偵測PATH環境變量,所以會直接使用與命令行一致的Maven環境。依次點擊菜單欄中的工具選項其餘Maven標籤欄,你就能看到如圖2-15所示的配置:

 



 圖2-15 在NetBeans中使用外部Maven

2.8 小結

本章詳細介紹了在各類操做系統平臺上安裝Maven,並對Maven安裝目錄進行了深刻的分析,在命令行的基礎上,本章又進一步介紹了Maven與主流IDE Eclipse及NetBeans的集成,本章最後還介紹了一些與Maven安裝相關的最佳實踐。本書下一章會建立一個Hello World項目,帶領讀者配置和構建Maven項目。

第3章 Maven使用入門

到目前爲止,咱們已經大概瞭解並安裝好了Maven,如今,咱們開始 建立一個最簡單的Hello World項目。若是你是初次接觸Maven,我建議你按照本章的內容一步步地編寫代碼並執行,可能你會碰到一些概念暫時難以理解,不用着急,記下這些疑 難點,相信本書的後續章節會幫你逐一解答。 
3.1 編寫POM 
3.2 編寫主代碼 
3.3 編寫測試代碼 
3.4 打包和運行 
3.5 使用Archetype生成項目骨架 
3.6 m2eclipse簡單使用 
3.7 NetBeans Maven插件簡單使用 
3.8 小結

3.1 編寫POM

就像Make的Makefile,Ant的build.xml同樣,Maven項目的核心是pom.xml。POM(Project Object Model,項目對象模型)定義了項目的基本信息,用於描述項目如何構建,聲明項目依賴,等等。如今咱們先爲Hello World項目編寫一個最簡單的pom.xml。

首先建立一個名爲hello-world的文件夾(本書中各章的代碼都會對應一個以ch開頭的項目),打開該文件夾,新建一個名爲pom.xml的文件,輸入其內容如代碼清單3-1:

代碼清單3-1:Hello World的POM

  1. <span style="font-size: small;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  
  5. http://maven.apache.org/maven-v4_0_0.xsd">  
  6.   <modelVersion>4.0.0</modelVersion>  
  7.   <groupId>com.juvenxu.mvnbook</groupId>  
  8.   <artifactId>hello-world</artifactId>  
  9.   <version>1.0-SNAPSHOT</version>  
  10.   <name>Maven Hello World Project</name>  
  11. </project>   
  12. </span>  

     代碼的第一行是XML頭,指定了該xml文檔的版本和編碼方式。緊接着是project元素,project是全部pom.xml的根元素,它還聲明瞭一些POM相關的命名空間及xsd元素,雖然這些屬性不是必須的,但使用這些屬性可以讓第三方工具(如IDE中的XML編輯器)幫助咱們快速編輯POM。

根元素下的第一個子元素modelVersion指定了當前POM模型的版本,對於Maven2及Maven 3來講,它只能是4.0.0。

這段代碼中最重要的是groupId,artifactId和version三行。這三個元素定義了一個項目基本的座標,在Maven的世界,任何的jar、pom或者war都是以基於這些基本的座標進行區分的。

groupId定義了項目屬於哪一個組,這個組每每和項目所在的組織或公司存在關聯,譬如你在googlecode上創建了一個名爲myapp的項目,那麼groupId就應該是com.googlecode.myapp,若是你的公司是mycom,有一個項目爲myapp,那麼groupId就應該是com.mycom.myapp。本書中全部的代碼都基於groupId com.juvenxu.mvnbook。

artifactId定義了當前Maven項目在組中惟一的ID,咱們爲這個Hello World項目定義artifactId爲hello-world,本書其餘章節代碼會被分配其餘的artifactId。而在前面的groupId爲com.googlecode.myapp的例子中,你可能會爲不一樣的子項目(模塊)分配artifactId,如:myapp-util、myapp-domain、myapp-web等等。

顧名思義,version指定了Hello World項目當前的版本——1.0-SNAPSHOT。SNAPSHOT意爲快照,說明該項目還處於開發中,是不穩定的版本。隨着項目的發展,version會不斷更新,如升級爲1.0、1.1-SNAPSHOT、1.一、2.0等等。本書的6.5小節會詳細介紹SNAPSHOT,第13章介紹如何使用Maven管理項目版本的升級發佈。

最後一個name元素聲明瞭一個對於用戶更爲友好的項目名稱,雖然這不是必須的,但我仍是推薦爲每一個POM聲明name,以方便信息交流。

沒有任何實際的Java代碼,咱們就可以定義一個Maven項目的POM,這體現了Maven的一大優勢,它能讓項目對象模型最大程度地與實際代碼相獨立,咱們能夠稱之爲解耦,或者正交性,這在很大程度上避免了Java代碼和POM代碼的相互影響。好比當項目須要升級版本時,只須要修改POM,而不須要更改Java代碼;而在POM穩定以後,平常的Java代碼開發工做基本不涉及POM的修改。

3.2 編寫主代碼

項目主代碼和測試代碼不一樣,項目的主代碼會被打包到最終的構件中(好比jar),而測試代碼只在運行測試時用到,不會被打包。默認狀況下,Maven假設項目主代碼位於src/main/java目錄,咱們遵循Maven的約定,建立該目錄,而後在該目錄下建立文件com/juvenxu/mvnbook/helloworld/HelloWorld.java,其內容如代碼清單3-2:

代碼清單3-2:Hello World的主代碼

  1. <span style="font-size: small;">package com.juvenxu.mvnbook.helloworld;  
  2.    
  3. public class HelloWorld  
  4. {  
  5.    public String sayHello()  
  6.    {  
  7.      return "Hello Maven";  
  8.    }  
  9.   
  10.   public static void main(String[] args)  
  11.    {  
  12.      System.out.print( new HelloWorld().sayHello() );  
  13.    }  
  14. }  
  15. </span>  

       這是一個簡單的Java類,它有一個sayHello()方法,返回一個String。同時這個類還帶有一個main方法,建立一個HelloWorld實例,調用sayHello()方法,並將結果輸出到控制檯。

關於該Java代碼有兩點須要注意。首先,在95%以上的狀況下,咱們應該把項目主代碼放到src/main/java/目錄下(遵循Maven的約定),而無須額外的配置,Maven會自動搜尋該目錄找到項目主代碼。其次,該Java類的包名是com.juvenxu.mvnbook.helloworld,這與咱們以前在POM中定義的groupId和artifactId相吻合。通常來講,項目中Java類的包都應該基於項目的groupId和artifactId,這樣更加清晰,更加符合邏輯,也方便搜索構件或者Java類。

代碼編寫完畢後,咱們使用Maven進行編譯,在項目根目錄下運行命令 mvn clean compile ,咱們會獲得以下輸出:

 

  1. <span style="font-size: small;">[INFO] Scanning for projects...  
  2. [INFO] ------------------------------------------------------------------------  
  3. [INFO] Building Maven Hello World Project  
  4. [INFO]    task-segment: [clean, compile]  
  5. [INFO] ------------------------------------------------------------------------  
  6. [INFO] [clean:clean {execution: default-clean}]  
  7. [INFO] Deleting directory D:\code\hello-world\target  
  8. [INFO] [resources:resources {execution: default-resources}]  
  9. [INFO] skip non existing resourceDirectory D: \code\hello-world\src\main\resources  
  10. [INFO] [compiler:compile {execution: default-compile}]  
  11. [INFO] Compiling 1 source file to D: \code\hello-world\target\classes  
  12. [INFO] ------------------------------------------------------------------------  
  13. [INFO] BUILD SUCCESSFUL  
  14. [INFO] ------------------------------------------------------------------------  
  15. [INFO] Total time: 1 second  
  16. [INFO] Finished at: Fri Oct 09 02:08:09 CST 2009  
  17. [INFO] Final Memory: 9M/16M  
  18. [INFO] ------------------------------------------------------------------------  
  19. </span>  

 

clean告訴Maven清理輸出目錄target/,compile告訴Maven編譯項目主代碼,從輸出中咱們看到Maven首先執行了clean:clean任務,刪除target/目錄,默認狀況下Maven構建的全部輸出都在target/目錄中;接着執行resources:resources任務(未定義項目資源,暫且略過);最後執行compiler:compile任務,將項目主代碼編譯至target/classes目錄(編譯好的類爲com/juvenxu/mvnbook/helloworld/HelloWorld.Class)。

上文提到的clean:clean、resources:resources,以及compiler:compile對應了一些Maven插件及插件目標,好比clean:clean是clean插件的clean目標,compiler:compile是compiler插件的compile目標,後文會詳細講述Maven插件及其編寫方法。

至此,Maven在沒有任何額外的配置的狀況下就執行了項目的清理和編譯任務,接下來,咱們編寫一些單元測試代碼並讓Maven執行自動化測試。

3.3 編寫測試代碼

爲了使項目結構保持清晰,主代碼與測試代碼應該分別位於獨立的目錄中。3.2節講過Maven項目中默認的主代碼目錄是src/main/java,對應地,Maven項目中默認的測試代碼目錄是src/test/java。所以,在編寫測試用例以前,咱們先建立該目錄。

在Java世界中,由Kent Beck和Erich Gamma創建的JUnit是事實上的單元測試標準。要使用JUnit,咱們首先須要爲Hello World項目添加一個JUnit依賴,修改項目的POM如代碼清單3-3:

代碼清單3-3:爲Hello World的POM添加依賴

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  
  5. http://maven.apache.org/maven-v4_0_0.xsd">  
  6.   <modelVersion>4.0.0</modelVersion>  
  7.   <groupId>com.juvenxu.mvnbook</groupId>  
  8.   <artifactId>hello-world</artifactId>  
  9.   <version>1.0-SNAPSHOT</version>  
  10.   <name>Maven Hello World Project</name>  
  11.   <dependencies>  
  12.     <dependency>  
  13.        <groupId>junit</groupId>  
  14.        <artifactId>junit</artifactId>  
  15.        <version>4.7</version>  
  16.        <scope>test</scope>  
  17.     </dependency>  
  18.   </dependencies>  
  19. </project>    

     代碼中添加了dependencies元素,該元素下能夠包含多個dependency元素以聲明項目的依賴,這裏咱們添加了一個依賴——groupId是junit,artifactId是junit,version是4.7。前面咱們提到groupId、artifactId和version是任何一個Maven項目最基本的座標,JUnit也不例外,有了這段聲明,Maven就可以自動下載junit-4.7.jar。也許你會問,Maven從哪裏下載這個jar呢?在Maven以前,咱們能夠去JUnit的官網下載分發包。而如今有了Maven,它會自動訪問中央倉庫(http://repo1.maven.org/maven2/),下載須要的文件。讀者也能夠本身訪問該倉庫,打開路徑junit/junit/4.7/,就能看到junit-4.7.pom和junit-4.7.jar。本書第6章會詳細介紹Maven倉庫及中央倉庫。

上述POM代碼中還有一個值爲test的元素scope,scope爲依賴範圍,若依賴範圍爲test則表示該依賴只對測試有效,換句話說,測試代碼中的import JUnit代碼是沒有問題的,可是若是咱們在主代碼中用import JUnit代碼,就會形成編譯錯誤。若是不聲明依賴範圍,那麼默認值就是compile,表示該依賴對主代碼和測試代碼都有效。

配置了測試依賴,接着就能夠編寫測試類,回顧一下前面的HelloWorld類,如今咱們要測試該類的sayHello()方法,檢查其返回值是否爲「Hello Maven」。在src/test/java目錄下建立文件,其內容如代碼清單3-4:

代碼清單3-4:Hello World的測試代碼

  1. package com.juvenxu.mvnbook.helloworld;  
  2. import static org.junit.Assert.assertEquals;  
  3. import org.junit.Test;  
  4.   
  5. public class HelloWorldTest  
  6. {  
  7.     @Test  
  8.     public void testSayHello()  
  9.     {  
  10.         HelloWorld helloWorld = new HelloWorld();  
  11.   
  12.         String result = helloWorld.sayHello();  
  13.   
  14.         assertEquals( "Hello Maven", result );  
  15.     }  
  16. }   

一個典型的單元測試包含三個步驟:一,準備測試類及數據;二,執行要測試的行爲;三,檢查結果。上述樣例中,咱們首先初始化了一個要測試的HelloWorld實例,接着執行該實例的sayHello()方法並保存結果到result變量中,最後使用JUnit框架的Assert類檢查結果是否爲咱們指望的」Hello Maven」。在JUnit 3中,約定全部須要執行測試的方法都以test開頭,這裏咱們使用了JUnit 4,但咱們仍然遵循這一約定,在JUnit 4中,須要執行的測試方法都應該以@Test進行標註。

測試用例編寫完畢以後就能夠調用Maven執行測試,運行 mvn clean test :

  1. [INFO] Scanning for projects...  
  2. [INFO] ------------------------------------------------------------------------  
  3. [INFO] Building Maven Hello World Project  
  4. [INFO]    task-segment: [clean, test]  
  5. [INFO] ------------------------------------------------------------------------  
  6. [INFO] [clean:clean {execution: default-clean}]  
  7. [INFO] Deleting directory D:\git-juven\mvnbook\code\hello-world\target  
  8. [INFO] [resources:resources {execution: default-resources}]  
  9. …  
  10. Downloading: http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom  
  11. 1K downloaded  (junit-4.7.pom)  
  12. [INFO] [compiler:compile {execution: default-compile}]  
  13. [INFO] Compiling 1 source file to D: \code\hello-world\target\classes  
  14. [INFO] [resources:testResources {execution: default-testResources}]  
  15. …  
  16. Downloading: http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.jar  
  17. 226K downloaded  (junit-4.7.jar)  
  18. [INFO] [compiler:testCompile {execution: default-testCompile}]  
  19. [INFO] Compiling 1 source file to D:\ code\hello-world\target\test-classes  
  20. [INFO] ------------------------------------------------------------------------  
  21. [ERROR] BUILD FAILURE  
  22. [INFO] ------------------------------------------------------------------------  
  23. [INFO] Compilation failure  
  24. D:\code\hello-world\src\test\java\com\juvenxu\mvnbook\helloworld\HelloWorldTest.java:[8,5] -source 1.3 中不支持註釋  
  25. (請使用 -source 5 或更高版本以啓用註釋)  
  26.     @Test  
  27. [INFO] ------------------------------------------------------------------------  
  28. [INFO] For more information, run Maven with the -e switch  
  29.   …  
 

不幸的是構建失敗了,不過咱們先耐心分析一下這段輸出(爲了本書的簡潔,一些不重要的信息我用省略號略去了)。命令行輸入的是mvn clean test,而Maven實際執行的可不止這兩個任務,還有clean:clean、resources:resources、compiler:compile、resources:testResources以及compiler:testCompile。暫時咱們須要瞭解的是,在Maven執行測試(test)以前,它會先自動執行項目主資源處理,主代碼編譯,測試資源處理,測試代碼編譯等工做,這是Maven生命週期的一個特性,本書後續章節會詳細解釋Maven的生命週期。

從輸出中咱們還看到:Maven從中央倉庫下載了junit-4.7.pom和junit-4.7.jar這兩個文件到本地倉庫(~/.m2/repository)中,供全部Maven項目使用。

構建在執行compiler:testCompile任務的時候失敗了,Maven輸出提示咱們須要使用-source 5或更高版本以啓動註釋,也就是前面提到的JUnit 4的@Test註解。這是Maven初學者經常會遇到的一個問題。因爲歷史緣由,Maven的核心插件之一compiler插件默認只支持編譯Java 1.3,所以咱們須要配置該插件使其支持Java 5,見代碼清單3-5:

代碼清單3-5:配置maven-compiler-plugin支持Java 5

  1. <project>  
  2. …  
  3.   <build>  
  4.     <plugins>  
  5.        <plugin>  
  6.          <groupId>org.apache.maven.plugins</groupId>  
  7.          <artifactId>maven-compiler-plugin</artifactId>  
  8.          <configuration>  
  9.            <source>1.5</source>  
  10.            <target>1.5</target>  
  11.          </configuration>  
  12.        </plugin>  
  13.     </plugins>  
  14.   </build>  
  15. …  
  16. </project>    

該POM省略了除插件配置之外的其餘部分,咱們暫且不去關心插件配置的細節,只須要知道compiler插件支持Java 5的編譯。如今再執行mvn clean test輸出以下:

  1. …  
  2. [INFO] [compiler:testCompile {execution: default-testCompile}]  
  3. [INFO] Compiling 1 source file to D: \code\hello-world\target\test-classes  
  4. [INFO] [surefire:test {execution: default-test}]  
  5. [INFO] Surefire report directory: D:\code\hello-world\target\surefire-reports  
  6. -------------------------------------------------------  
  7.  T E S T S  
  8. -------------------------------------------------------  
  9. Running com.juvenxu.mvnbook.helloworld.HelloWorldTest  
  10. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 sec  
  11. Results :  
  12. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0  
  13. [INFO] ------------------------------------------------------------------------  
  14. [INFO] BUILD SUCCESSFUL  
  15. [INFO] ------------------------------------------------------------------------  
  16. …  

咱們看到compiler:testCompile任務執行成功了,測試代碼經過編譯以後在target/test-classes下生成了二進制文件,緊接着surefire:test任務運行測試,surefire是Maven世界中負責執行測試的插件,這裏它運行測試用例HelloWorldTest,而且輸出測試報告,顯示一共運行了多少測試,失敗了多少,出錯了多少,跳過了多少。顯然,咱們的測試經過了——BUILD SUCCESSFUL。

3.4 打包和運行

將項目進行編譯、測試以後,下一個重要步驟就是打包(package)。Hello World的POM中沒有指定打包類型,使用默認打包類型jar,咱們能夠簡單地執行命令 mvn clean package 進行打包,能夠看到以下輸出:

  1. …  
  2. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0  
  3.   
  4. [INFO] [jar:jar {execution: default-jar}]  
  5. [INFO] Building jar: D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar  
  6. [INFO]   
  7. --------------------------------------------------------------------  
  8. [INFO] BUILD SUCCESSFUL  
  9. …  
 

相似地,Maven會在打包以前執行編譯、測試等操做。這裏咱們看到jar:jar任務負責打包,實際上就是jar插件的jar目標將項目主代碼打包成一個名爲hello-world-1.0-SNAPSHOT.jar的文件,該文件也位於target/輸出目錄中,它是根據artifact-version.jar規則進行命名的,若有須要,咱們還能夠使用finalName來自定義該文件的名稱,這裏暫且不展開,本書後面會詳細解釋。

至此,咱們獲得了項目的輸出,若是有須要的話,就能夠複製這個jar文件到其餘項目的Classpath中從而使用HelloWorld類。可是,如何才能讓其餘的Maven項目直接引用這個jar呢?咱們還須要一個安裝的步驟,執行 mvn clean install

  1.    …  
  2.    [INFO] [jar:jar {execution: default-jar}]  
  3.    [INFO] Building jar: D: \code\hello-world\target\hello-world-1.0-SNAPSHOT.jar  
  4.    [INFO] [install:install {execution: default-install}]  
  5.    [INFO] Installing D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar to C:\Users\juven\.m2\repository\com\juvenxu\mvnbook\hello-world\1.0-SNAPSHOT\hello-world-1.0-SNAPSHOT.jar  
  6.    [INFO]  
  7. ------------------------------------------------------------------------  
  8.    [INFO] BUILD SUCCESSFUL  
  9.    …  

在打包以後,咱們又執行了安裝任務install:install,從輸出咱們看到該任務將項目輸出的jar安裝到了Maven本地倉庫中,咱們能夠打開相應的文件夾看到Hello World項目的pom和jar。以前講述JUnit的POM及jar的下載的時候,咱們說只有構件被下載到本地倉庫後,才能由全部Maven項目使用,這裏是一樣的道理,只有將Hello World的構件安裝到本地倉庫以後,其餘Maven項目才能使用它。

咱們已經將體驗了Maven最主要的命令:mvn clean compile、mvn clean test、mvn clean package、mvn clean install。執行test以前是會先執行compile的,執行package以前是會先執行test的,而相似地,install以前會執行package。咱們能夠在任何一個Maven項目中執行這些命令,並且咱們已經清楚它們是用來作什麼的。

到目前爲止,咱們尚未運行Hello World項目,不要忘了HelloWorld類但是有一個main方法的。默認打包生成的jar是不可以直接運行的,由於帶有main方法的類信息不會添加到manifest中(咱們能夠打開jar文件中的META-INF/MANIFEST.MF文件,將沒法看到Main-Class一行)。爲了生成可執行的jar文件,咱們須要藉助maven-shade-plugin,配置該插件以下:

  1. <plugin>  
  2. <groupId>org.apache.maven.plugins</groupId>  
  3.   <artifactId>maven-shade-plugin</artifactId>  
  4.   <version>1.2.1</version>  
  5.   <executions>  
  6.     <execution>  
  7.       <phase>package</phase>  
  8.       <goals>  
  9.         <goal>shade</goal>  
  10.       </goals>  
  11.       <configuration>  
  12.         <transformers>  
  13.           <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">            <mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>  
  14.          </transformer>  
  15.        </transformers>  
  16.      </configuration>  
  17.      </execution>  
  18.   </executions>  
  19. </plugin>  
 

plugin元素在POM中的相對位置應該在<project><build><plugins>下面。咱們配置了mainClass爲com.juvenxu.mvnbook.helloworld.HelloWorld,項目在打包時會將該信息放到MANIFEST中。如今執行 mvn clean install ,待構建完成以後打開target/目錄,咱們能夠看到hello-world-1.0-SNAPSHOT.jaroriginal-hello-world-1.0-SNAPSHOT.jar,前者是帶有Main-Class信息的可運行jar,後者是原始的jar,打開hello-world-1.0-SNAPSHOT.jarMETA-INF/MANIFEST.MF,能夠看到它包含這樣一行信息:

Main-Class: com.juvenxu.mvnbook.helloworld.HelloWorld

如今,咱們在項目根目錄中執行該jar文件:

D: \code\hello-world>java -jar target\hello-world-1.0-SNAPSHOT.jar

Hello Maven

控制檯輸出爲Hello Maven,這正是咱們所指望的。

本小節介紹了Hello World項目,側重點是Maven而非Java代碼自己,介紹了POM、Maven項目結構、以及如何編譯、測試、打包,等等。

3.5 使用Archetype生成項目骨架

Hello World項目中有一些Maven的約定:在項目的根目錄中放置pom.xml,在src/main/java目錄中放置項目的主代碼,在src/test/java中放置項目的測試代碼。我之因此一步一步地展現這些步驟,是爲了能讓多是Maven初學者的你獲得最實際的感覺。咱們稱這些基本的目錄結構和pom.xml文件內容稱爲項目的骨架,當你第一次建立項目骨架的時候,你還會饒有興趣地去體會這些默認約定背後的思想,第二次,第三次,你也許還會滿意本身的熟練程度,但第4、第五次作一樣的事情,就會讓程序員惱火了,爲此Maven提供了Archetype以幫助咱們快速勾勒出項目骨架。

仍是以Hello World爲例,咱們使用maven archetype來建立該項目的骨架,離開當前的Maven項目目錄。

若是是Maven 3,簡單的運行:

mvn archetype:generate

若是是Maven 2,最好運行以下命令:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate

不少資料會讓你直接使用更爲簡單的 mvn archetype:generate 命令,但在Maven2中這是不安全的,由於該命令沒有指定archetype插件的版本,因而Maven會自動去下載最新的版本,進而可能獲得不穩定的SNAPSHOT版本,致使運行失敗。然而在Maven 3中,即便用戶沒有指定版本,Maven也只會解析最新的穩定版本,所以這是安全的,具體內容見7.7小節。

咱們其實是在運行插件maven-archetype-plugin,注意冒號的分隔,其格式爲 groupId:artifactId:version:goal,org.apache.maven.plugins 是maven官方插件的groupId,maven-archetype-plugin 是archetype插件的artifactId,2.0-alpha-5 是目前該插件最新的穩定版,generate是咱們要使用的插件目標。

緊接着咱們會看到一段長長的輸出,有不少可用的archetype供咱們選擇,包括著名的Appfuse項目的archetype,JPA項目的archetype等等。每個archetype前面都會對應有一個編號,同時命令行會提示一個默認的編號,其對應的archetype爲maven-archetype-quickstart,咱們直接回車以選擇該archetype,緊接着Maven會提示咱們輸入要建立項目的groupId、artifactId、 version、以及包名package,以下輸入並確認:

  1. Define value for groupId: : com.juvenxu.mvnbook  
  2. Define value for artifactId: : hello-world  
  3. Define value for version:  1.0-SNAPSHOT: :  
  4. Define value for package:  com.juvenxu.mvnbook: : com.juvenxu.mvnbook.helloworld  
  5. Confirm properties configuration:  
  6. groupId: com.juvenxu.mvnbook  
  7. artifactId: hello-world  
  8. version: 1.0-SNAPSHOT  
  9. package: com.juvenxu.mvnbook.helloworld  
  10.  Y: : Y  

Archetype插件將根據咱們提供的信息建立項目骨架。在當前目錄下,Archetype插件會建立一個名爲hello-world(咱們定義的artifactId)的子目錄,從中能夠看到項目的基本結構:基本的pom.xml已經被建立,裏面包含了必要的信息以及一個junit依賴;主代碼目錄src/main/java已經被建立,在該目錄下還有一個Java類com.juvenxu.mvnbook.helloworld.App,注意這裏使用到了咱們剛纔定義的包名,而這個類也僅僅只有一個簡單的輸出Hello World!的main方法;測試代碼目錄src/test/java也被建立好了,而且包含了一個測試用例com.juvenxu.mvnbook.helloworld.AppTest

Archetype能夠幫助咱們迅速地構建起項目的骨架,在前面的例子中,咱們徹底能夠在Archetype生成的骨架的基礎上開發Hello World項目以節省咱們大量時間。

此外,咱們這裏僅僅是看到了一個最簡單的archetype,若是你有不少項目擁有相似的自定義項目結構以及配置文件,你徹底能夠一勞永逸地開發本身的archetype,而後在這些項目中使用自定義的archetype來快速生成項目骨架,本書後面的章節會詳細闡述如何開發Maven Archetype。

3.6 m2eclipse簡單使用

介紹前面Hello World項目的時候,咱們並無涉及IDE,如此簡單的一個項目,使用最簡單的編輯器也能很快完成,但對於稍微大一些的項目來講,沒有IDE就是不可想象的,本節咱們先介紹m2eclipse的基本使用。

3.6.1 導入Maven項目

第2章介紹瞭如何安裝m2eclipse,如今,咱們使用m2ecilpse導入Hello World項目。選擇菜單項File,而後選擇Import,咱們會看到一個Import對話框,在該對話框中選擇General目錄下的Maven Projects,而後點擊Next,就會出現Import Projects對話框,在該對話框中點擊Browse…選擇Hello World的根目錄(即包含pom.xml文件的那個目錄),這時對話框中的Projects:部分就會顯示該目錄包含的Maven項目,如圖3-1所示:


 圖3-1 在Eclipse中導入Maven項目

點擊Finish以後,m2ecilpse就會將該項目導入到當前的workspace中,導入完成以後,咱們就能夠在Package Explorer視圖中看到如圖3-2所示的項目結構:

 圖3-2 Eclipse中導入的Maven項目結構

咱們看到主代碼目錄src/main/java和測試代碼目錄src/test/java成了Eclipse中的資源目錄,包和類的結構也十分清晰,固然pom.xml永遠在項目的根目錄下,而從這個視圖中咱們甚至還能看到項目的依賴junit-4.7.jar,其實際的位置指向了Maven本地倉庫(這裏我自定義了Maven本地倉庫地址爲D:\java\repository,後續章節會介紹如何自定義本地倉庫位置)。

3.6.2 建立Maven項目

建立一個Maven項目也十分簡單,選擇菜單項File -> New -> Other,在彈出的對話框中選擇Maven下的Maven Project,而後點擊Next >,在彈出的New Maven Project對話框中,咱們使用默認的選項(不要選擇Create a simple project選項,那樣咱們就能使用Maven Archetype),點擊Next >,此時m2eclipse會提示咱們選擇一個Archetype,咱們選擇maven-archetype-quickstart,再點擊Next >。因爲m2eclipse其實是在使用maven-archetype-plugin插件建立項目,所以這個步驟與上一節咱們使用archetype建立項目骨架相似,輸入groupId,、artifactId、version、package(暫時咱們不考慮Properties),如圖3-3所示:


 圖3-3 在Eclipse中使用Archetype建立項目

注意,爲了避免和前面已導入的Hello World項目產生衝突和混淆,咱們使用不一樣的artifactId和package。OK,點擊Finish,Maven項目就建立完成了,其結構與前一個已導入的Hello World項目基本一致。

3.6.3 運行mvn命令

咱們須要在命令行輸入如mvn clean install之類的命令來執行maven構建,m2eclipse中也有對應的功能,在Maven項目或者pom.xml上右擊,再選擇Run As,就能看到以下的常見Maven命令,如圖3-4所示:


 圖3-4 在Eclipse中運行默認mvn命令

選擇想要執行的Maven命令就能執行相應的構建,同時咱們也能在Eclipse的console中看到構建輸出。這裏常見的一個問題是,默認選項中沒有咱們想要執行的Maven命令怎麼辦?好比,默認帶有mvn test,但咱們想執行mvn clean test,很簡單,選擇Maven buid… 以自定義Maven運行命令,在彈出對話框中的Goals一項中輸入咱們想要執行的命令,如clean test,設置一下Name,點擊Run便可。而且,下一次咱們選擇Maven build,或者使用快捷鍵Alt + Shift + X, M快速執行Maven構建的時候,上次的配置直接就能在歷史記錄中找到。圖3-5就是自定義Maven運行命令的界面:


 圖3-5 在Eclipse中自定義mvn命令

3.7 NetBeans Maven插件簡單使用

NetBeans的Maven插件也十分簡單易用,咱們能夠輕鬆地在NetBeans中導入現有的Maven項目,或者使用Archetype建立Maven項目,咱們也可以在NetBeans中直接運行mvn命令。

3.7.1 打開Maven項目

與其說打開Maven項目,不如稱之爲導入更爲合適,由於這個項目不須要是NetBeans建立的Maven項目,不過這裏咱們仍是遵守NetBeans菜單中使用的名稱。

選擇菜單欄中的文件,而後選擇打開項目,直接定位到Hello World項目的根目錄,NetBeans會十分智能地識別出Maven項目,如圖3-6所示:


圖3-6 在NetBeans中導入Maven項目

Maven項目的圖標有別於通常的文件夾,點擊打開項目後,Hello World項目就會被導入到NetBeans中,在項目視圖中能夠看到如圖3-7所示的項目結構:


 圖3-7 NetBeans中導入的Maven項目結構

NetBeans中項目主代碼目錄的名稱爲源包,測試代碼目錄成了測試包,編譯範圍依賴爲,測試範圍依賴爲測試庫,這裏咱們也能看到pom.xml,NetBeans甚至還幫咱們引用了settings.xml。

3.7.2 建立Maven項目

在NetBeans中建立Maven項目一樣十分輕鬆,在菜單欄中選擇文件,而後新建項目,在彈出的對話框中,選擇項目類別爲Maven,項目爲Maven項目,點擊「下一步」以後,對話框會提示咱們選擇Maven原型(即Maven Archtype),咱們選擇Maven快速啓動原型(1.0,(即前文提到的maven-archetype-quickstart),點擊「下一步」以後,輸入項目的基本信息,這些信息在以前討論archetype及在m2eclipse中建立Maven項目的時候都仔細解釋過,再也不詳述,如圖3-8所示:


 圖3-8 在NetBeans中使用Archetype建立Maven項目

點擊完成以後,一個新的Maven項目就建立好了。

3.7.3 運行mvn命令

NetBeans在默認狀況下提供兩種Maven運行方式,點擊菜單欄中的運行,咱們能夠看到生成項目清理並生成項目兩個選項,咱們能夠嘗試「點擊運行Maven構建」,根據NetBeans控制檯的輸出,咱們就能發現它們實際上對應了mvn installmvn clean install兩個命令。

在實際開發過程當中,咱們每每不會知足於這兩種簡單的方式,好比,有時候咱們只想執行項目的測試,而不須要打包,這時咱們就但願可以執行mvn clean test命令,所幸的是NetBeans Maven插件徹底支持自定義的mvn命令配置。

在菜單欄中選擇工具,接着選擇選項,在對話框中,最上面一欄選擇其餘,下面選擇Maven標籤欄,在這裏咱們能夠對NetBeans Maven插件進行全局的配置(還記得第2章中咱們如何配置NetBeans使用外部Maven麼?)。如今,選擇倒數第三行的編輯全局定製目標定義,咱們添加一個名爲Maven Test的操做,執行目標爲clean test,暫時不考慮其餘配置選項,如圖3-9所示:

 

圖3-9 在NetBeans中自定義mvn命令

點擊「缺省保存該配置」,在Maven項目上右擊,選擇定製,就能看到剛纔配置好的Maven運行操做,選擇Maven Test以後,終端將執行mvn clean test。值得一提的是,咱們也能夠在項目上右擊,選擇定製,再選擇目標再輸入想要執行的Maven目標(如clean package),點擊肯定以後NetBeans就會執行相應的Maven命令。這種方式十分便捷,但這是臨時的,該配置不會被保存,也不會有歷史記錄。

3.8 小結

本章以儘量簡單且詳細的方式敘述了一個Hello World項目,重點解釋了POM的基本內容、Maven項目的基本結構、以及構建項目基本的Maven命令。在此基礎上,還介紹瞭如何使用 Archetype快速建立項目骨架。最後講述的是如何在Eclipse和NetBeans中導入、建立及構建Maven項目。
相關文章
相關標籤/搜索