Maven經典使用指南

FeelTouch發表於2018-06-18

1.前言 

Maven,發音是[`meivin],"專家"的意思。它是一個很好的專案管理工具,很早就進入了我的必備工具行列,但是這次為了把project1專案完全遷移並應用maven,所以對maven進行了一些深入的學習。寫這個學習筆記的目的,一個是為了自己備忘,二則希望能夠為其他人學習使用maven 縮短一些時間。 

    2.命令 

    mvn pom.xml檔案配置詳解 
    http://maven.apache.org/ref/2.0.8/maven-model/maven.html 

    mvn -version/-v 顯示版本資訊 
    mvn archetype:generate   建立mvn專案 
    mvn archetype:create -DgroupId=com.oreilly -DartifactId=my-app   建立mvn專案 

    mvn package    生成target目錄,編譯、測試程式碼,生成測試報告,生成jar/war檔案 
    mvn jetty:run    執行專案於jetty上, 
    mvn compile      編譯 
    mvn test      編譯並測試 
    mvn clean      清空生成的檔案 
    mvn site      生成專案相關資訊的網站 
    mvn -Dwtpversion=1.0 eclipse:eclipse   生成Wtp外掛的Web專案 
    mvn -Dwtpversion=1.0 eclipse:clean   清除Eclipse專案的配置資訊(Web專案) 
    mvn eclipse:eclipse     將專案轉化為Eclipse專案 

    在應用程式用使用多個儲存庫 
    <repositories>    
    <repository>      
       <id>Ibiblio</id>      
       <name>Ibiblio</name>      
       <url>http://www.ibiblio.org/maven/</url>    
    </repository>    
    <repository>      
       <id>PlanetMirror</id>      
       <name>Planet Mirror</name>      
       <url>http://public.planetmirror.com/pub/maven/</url>    
    </repository> 
    </repositories> 


    mvn deploy:deploy-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar -DrepositoryId=maven-repository-inner -Durl=ftp://xxxxxxx/opt/maven/repository/ 


    釋出第三方Jar到本地庫中: 

    mvn install:install-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar 


    -DdownloadSources=true 

    -DdownloadJavadocs=true 

    mvn -e    顯示詳細錯誤 資訊. 

    mvn validate   驗證工程是否正確,所有需要的資源是否可用。 
    mvn test-compile 編譯專案測試程式碼。 。 
    mvn integration-test 在整合測試可以執行的環境中處理和釋出包。 
    mvn verify   執行任何檢查,驗證包是否有效且達到質量標準。 
    mvn generate-sources 產生應用需要的任何額外的原始碼,如xdoclet。 

2. maven概要 

首先我把maven的概念快速的梳理一下,讓我們快速地建立起一個比較精確的maven應用場景。 
2.1 maven不是什麼 

讀書時候要先限定範圍,避免一些有害的遐想。要說maven不是什麼,我們可以從如下幾個要點來展開 

    maven不是ant,也不是make。 
    我們以前接觸的構建工具,需要寫一些詳細的步驟,比如: compile project1/src/*.java 等類似的語句。這些語句正是我們使用ant和make所要編寫的東西。maven採用了"約定優於配置"的方法,一些開發常用的操作和步驟已經固化在 maven中,所以使用者不再需要去編寫那些煩人的語句了。同時,maven內建了開發流程的支援,它不僅能夠編譯,同樣能夠打包、釋出,也能夠一氣呵成做完這些所有的步驟。 
    maven不是ivy 
    依賴管理是maven的功能之一,雖然很多人包括我以前都是隻用它的依賴管理功能,但是要深入運用的話,我們就可以看到更多的內容。更重要的是,maven在依賴關係中加入了scope的概念,進一步細化了依賴關係的劃分。 

2.2 maven是什麼 

maven將自己定位為一個專案管理工具。它負責管理專案開發過程中的幾乎所有的東西: 

    版本 
    maven有自己的版本定義和規則 
    構建 
    maven支援許多種的應用程式型別,對於每一種支援的應用程式型別都定義好了一組構建規則和工具集。 
    輸出物管理 
    maven可以管理專案構建的產物,並將其加入到使用者庫中。這個功能可以用於專案組和其他部門之間的交付行為。 
    依賴關係 
    maven對依賴關係的特性進行細緻的分析和劃分,避免開發過程中的依賴混亂和相互汙染行為 
    文件和構建結果 
    maven的site命令支援各種文件資訊的釋出,包括構建過程的各種輸出,javadoc,產品文件等。 
    專案關係 
    一個大型的專案通常有幾個小專案或者模組組成,用maven可以很方便地管理 
    移植性管理 
    maven可以針對不同的開發場景,輸出不同種類的輸出結果。 

2.3 maven的生命週期 

maven把專案的構建劃分為不同的生命週期(lifecycle),在我看來,劃分的已經是非常仔細了,大家可以參考這裡。粗略一點的話,它這個過程(phase)包括:編譯、測試、打包、整合測試、驗證、部署。maven中所有的執行動作(goal)都需要指明自己在這個過程中的執行位置,然後maven執行的時候,就依照過程的發展依次呼叫這些goal進行各種處理。 

這個也是maven的一個基本排程機制。一般來說,位置稍後的過程都會依賴於之前的過程。當然,maven同樣提供了配置檔案,可以依照使用者要求,跳過某些階段。 
2.4 maven的"約定優於配置" 

所謂的"約定優於配置",在maven中並不是完全不可以修改的,他們只是一些配置的預設值而已。但是使用者除非必要,並不需要去修改那些約定內容。maven預設的檔案存放結構如下: 

    /專案目錄 
        pom.xml 用於maven的配置檔案 
        /src 原始碼目錄 
            /src/main 工程原始碼目錄 
                /src/main/java 工程java原始碼目錄 
            /src/main/resource 工程的資源目錄 
            /src/test 單元測試目錄 
                /src/test/java 
        /target 輸出目錄,所有的輸出物都存放在這個目錄下 
            /target/classes 編譯之後的class檔案 

每一個階段的任務都知道怎麼正確完成自己的工作,比如compile任務就知道從src/main/java下編譯所有的java檔案,並把它的輸出class檔案存放到target/classes中。 

對maven來說,採用"約定優於配置"的策略可以減少修改配置的工作量,也可以降低學習成本,更重要的是,給專案引入了統一的規範。 
2.5 maven的版本規範 

maven使用如下幾個要素來唯一定位某一個輸出物: groupId:artifactId:packaging:version 。比如org.springframework:spring:2.5 。每個部分的解釋如下: 

    groupId 
    團體,公司,小組,組織,專案,或者其它團體。團體標識的約定是,它以建立這個專案的組織名稱的逆向域名(reverse domain name)開頭。來自Sonatype的專案有一個以com.sonatype開頭的groupId,而Apache Software的專案有以org.apache開頭的groupId。 
    artifactId 
    在groupId下的表示一個單獨專案的唯一識別符號。比如我們的tomcat, commons等。不要在artifactId中包含點號(.)。 
    version 
    一個專案的特定版本。釋出的專案有一個固定的版本標識來指向該專案的某一個特定的版本。而正在開發中的專案可以用一個特殊的標識,這種標識給版本加上一個"SNAPSHOT"的標記。 
    雖然專案的打包格式也是Maven座標的重要組成部分,但是它不是專案唯一識別符號的一個部分。一個專案的 groupId:artifactId:version使之成為一個獨一無二的專案;你不能同時有一個擁有同樣的groupId, artifactId和version標識的專案。 
    packaging 
    專案的型別,預設是jar,描述了專案打包後的輸出。型別為jar的專案產生一個JAR檔案,型別為war的專案產生一個web應用。 
    classifier 
    很少使用的座標,一般都可以忽略classifiers。如果你要釋出同樣的程式碼,但是由於技術原因需要生成兩個單獨的構件,你就要使用一個分類器(classifier)。例如,如果你想要構建兩個單獨的構件成JAR,一個使用Java 1.4編譯器,另一個使用Java 6編譯器,你就可以使用分類器來生成兩個單獨的JAR構件,它們有同樣的groupId:artifactId:version組合。如果你的專案使用本地擴充套件類庫,你可以使用分類器為每一個目標平臺生成一個構件。分類器常用於打包構件的原始碼,JavaDoc或者二進位制集合。 

maven有自己的版本規範,一般是如下定義 <major version>.<minor version>.<incremental version>-<qualifier> ,比如1.2.3-beta-01。要說明的是,maven自己判斷版本的演算法是major,minor,incremental部分用數字比較,qualifier部分用字串比較,所以要小心 alpha-2和alpha-15的比較關係,最好用 alpha-02的格式。 

maven在版本管理時候可以使用幾個特殊的字串 SNAPSHOT ,LATEST ,RELEASE 。比如"1.0-SNAPSHOT"。各個部分的含義和處理邏輯如下說明: 

    SNAPSHOT 
    如果一個版本包含字串"SNAPSHOT",Maven就會在安裝或釋出這個元件的時候將該符號展開為一個日期和時間值,轉換為UTC時間。例如,"1.0-SNAPSHOT"會在2010年5月5日下午2點10分發布時候變成1.0-20100505-141000-1。 
    這個詞只能用於開發過程中,因為一般來說,專案組都會頻繁釋出一些版本,最後實際釋出的時候,會在這些snapshot版本中尋找一個穩定的,用於正式釋出,比如1.4版本釋出之前,就會有一系列的1.4-SNAPSHOT,而實際釋出的1.4,也是從中拿出來的一個穩定版。 
    LATEST 
    指某個特定構件的最新發布,這個釋出可能是一個釋出版,也可能是一個snapshot版,具體看哪個時間最後。 
    RELEASE 
    指最後一個釋出版。 

2.6 maven的組成部分 

maven把整個maven管理的專案分為幾個部分,一個部分是原始碼,包括原始碼本身、相關的各種資源,一個部分則是單元測試用例,另外一部分則是各種maven的外掛。對於這幾個部分,maven可以獨立管理他們,包括各種外部依賴關係。 
2.7 maven的依賴管理 

依賴管理一般是最吸引人使用maven的功能特性了,這個特性讓開發者只需要關注程式碼的直接依賴,比如我們用了spring,就加入spring依賴說明就可以了,至於spring自己還依賴哪些外部的東西,maven幫我們搞定。 

任意一個外部依賴說明包含如下幾個要素:groupId, artifactId, version, scope, type, optional。其中前3個是必須的,各自含義如下: 

    groupId 必須 
    artifactId 必須 
    version 必須。 
    這裡的version可以用區間表示式來表示,比如(2.0,)表示>2.0,[2.0,3.0)表示2.0<=ver<3.0;多個條件之間用逗號分隔,比如[1,3),[5,7]。 
    scope 作用域限制 
    type 一般在pom引用依賴時候出現,其他時候不用 
    optional 是否可選依賴 

maven認為,程式對外部的依賴會隨著程式的所處階段和應用場景而變化,所以maven中的依賴關係有作用域(scope)的限制。在maven中,scope包含如下的取值: 

    compile(編譯範圍) 
    compile是預設的範圍;如果沒有提供一個範圍,那該依賴的範圍就是編譯範圍。編譯範圍依賴在所有的classpath中可用,同時它們也會被打包。 
    provided(已提供範圍) 
    provided依賴只有在當JDK或者一個容器已提供該依賴之後才使用。例如,如果你開發了一個web應用,你可能在編譯classpath中需要可用的Servlet API來編譯一個servlet,但是你不會想要在打包好的WAR中包含這個Servlet API;這個Servlet API JAR由你的應用伺服器或者servlet容器提供。已提供範圍的依賴在編譯classpath(不是執行時)可用。它們不是傳遞性的,也不會被打包。 
    runtime(執行時範圍) 
    runtime依賴在執行和測試系統的時候需要,但在編譯的時候不需要。比如,你可能在編譯的時候只需要JDBC API JAR,而只有在執行的時候才需要JDBC驅動實現。 
    test(測試範圍) 
    test範圍依賴 在一般的 編譯和執行時都不需要,它們只有在測試編譯和測試執行階段可用。測試範圍依賴在之前的???中介紹過。 
    system(系統範圍) 
    system範圍依賴與provided類似,但是你必須顯式的提供一個對於本地系統中JAR檔案的路徑。這麼做是為了允許基於本地物件編譯,而這些物件是系統類庫的一部分。這樣的構件應該是一直可用的,Maven也不會在倉庫中去尋找它。 如果你將一個依賴範圍設定成系統範圍,你必須同時提供一個systemPath元素 。注意該範圍是不推薦使用的(你應該一直儘量去從公共或定製的Maven倉庫中引用依賴)。 

另外,程式碼有程式碼自己的依賴,各個maven使用的外掛也可以有自己的依賴關係。依賴也可以是可選的,比如我們程式碼中沒有任何cache依賴,但是hibernate可能要配置cache,所以該cache的依賴就是可選的。 
2.8 多專案管理 

maven的多專案管理也是非常強大的。一般來說,maven要求同一個工程的所有子專案都放置到同一個目錄下,每一個子目錄代表一個專案,比如 

    總專案/ 
        pom.xml 總專案的pom配置檔案 
        子專案1/ 
            pom.xml 子專案1的pom檔案 
        子專案2/ 
            pom.xml 子專案2的pom檔案 

按照這種格式存放,就是繼承方式,所有具體子專案的pom.xml都會繼承總專案pom的內容,取值為子專案pom內容優先。 

要設定繼承方式,首先要在總專案的pom中加入如下配置 
<modules> 
    <module>simple-weather</module> 
    <module>simple-webapp</module> 
</modules> 
        

其次在每個子專案中加入 
<parent> 
    <groupId>org.sonatype.mavenbook.ch06</groupId> 
    <artifactId>simple-parent</artifactId> 
    <version>1.0</version> 
</parent>  

即可。 

當然,繼承不是唯一的配置檔案共用方式,maven還支援引用方式。引用pom的方式更簡單,在依賴中加入一個type為pom的依賴即可。 

<project> 
    <description>This is a project requiring JDBC</description> 
    ... 
    <dependencies> 
        ... 
        <dependency> 
            <groupId>org.sonatype.mavenbook</groupId> 
            <artifactId>persistence-deps</artifactId> 
            <version>1.0</version> 
            <type>pom</type> 
        </dependency> 
    </dependencies> 
</project> 
        
2.9 屬性 

使用者可以在maven中定義一些屬性,然後在其他地方用${xxx}進行引用。比如: 

<project> 
    <modelVersion>4.0.0</modelVersion> 
    ... 
    <properties> 
        <var1>value1</var1> 
    </properties> 
</project> 
maven提供了三個隱式的變數,用來訪問系統環境變數、POM資訊和maven的settings: 

    env 
    暴露作業系統的環境變數,比如env.PATH 
    project 
    暴露POM中的內容,用點號(.)的路徑來引用POM元素的值,比如${project.artifactId}。另外,java的系統屬性比如user.dir等,也暴露在這裡。 
    settings 
    暴露maven的settings的資訊,也可以用點號(.)來引用。maven把系統配置檔案存放在maven的安裝目錄中,把使用者相關的配置檔案存放在~/.m2/settings.xml(unix)或者%USERPROFILE%/.m2/settings.xml(windows)中。 

2.10 maven的profile 

profile是maven的一個重要特性,它可以讓maven能夠自動適應外部的環境變化,比如同一個專案,在linux下編譯linux的版本,在win下編譯win的版本等。一個專案可以設定多個profile,也可以在同一時間設定多個profile被啟用(active)的。自動啟用的 profile的條件可以是各種各樣的設定條件,組合放置在activation節點中,也可以通過命令列直接指定。profile包含的其他配置內容可以覆蓋掉pom定義的相應值。如果認為profile設定比較複雜,可以將所有的profiles內容移動到專門的 profiles.xml 檔案中,不過記得和pom.xml放在一起。 

activation節點中的啟用條件中常見的有如下幾個: 

    os 
    判斷作業系統相關的引數,它包含如下可以自由組合的子節點元素 
        message - 規則失敗之後顯示的訊息 
        arch - 匹配cpu結構,常見為x86 
        family - 匹配作業系統家族,常見的取值為:dos,mac,netware,os/2,unix,windows,win9x,os/400等
        name - 匹配作業系統的名字 
        version - 匹配的作業系統版本號 
        display - 檢測到作業系統之後顯示的資訊 
    jdk 
    檢查jdk版本,可以用區間表示。 
    property 
    檢查屬性值,本節點可以包含name和value兩個子節點。 
    file 
    檢查檔案相關內容,包含兩個子節點:exists和missing,用於分別檢查檔案存在和不存在兩種情況。 

3. maven的操作和使用 

maven的操作有兩種方式,一種是通過mvn命令列命令,一種是使用maven的eclipse外掛。因為使用eclipse的maven外掛操作起來比較容易,這裡就只介紹使用mvn命令列的操作。 
3.1 maven的配置檔案 

maven的主執行程式為mvn.bat,linux下為mvn.sh,這兩個程式都很簡單,它們的共同用途就是收集一些引數,然後用 java.exe來執行maven的Main函式。maven同樣需要有配置檔案,名字叫做settings.xml,它放在兩個地方,一個是maven 安裝目錄的conf目錄下,對所有使用該maven的使用者都起作用,我們稱為主配置檔案,另外一個放在 %USERPROFILE%/.m2/settings.xml下,我們成為使用者配置檔案,只對當前使用者有效,且可以覆蓋主配置檔案的引數內容。還有就是專案級別的配置資訊了,它存放在每一個maven管理的專案目錄下,叫pom.xml,主要用於配置專案相關的一些內容,當然,如果有必要,使用者也可以在 pom中寫一些配置,覆蓋住配置檔案和使用者配置檔案的設定引數內容。 

一般來說,settings檔案配置的是比如repository庫路徑之類的全域性資訊,具體可以參考官方網站的文章 。 
3.2 建立新工程 

要建立一個新的maven工程,我們需要給我們的工程指定幾個必要的要素,就是maven產品座標的幾個要素:groupId, artifactId,如果願意,你也可以指定version和package名稱。我們先看一個簡單的建立命令: 

d:\work\temp>mvn archetype:create -DgroupId=com.abc -DartifactId=product1 -DarchetypeArtifactId=maven-archetype-webapp 

首先看這裡的命令列引數的傳遞結構,怪異的 -D引數=值 的方式是 java.exe 要求的方式。這個命令建立一個web工程,目錄結構是一個標準的maven結構,如下: 
D:. 
└─mywebapp 
    │  pom.xml 
    │ 
    └─src 
        └─main 
            ├─resources 
            └─webapp 
                │  index.jsp 
                │ 
                └─WEB-INF 
                    web.xml 

大家要注意,這裡目錄結構的佈局實際上是由引數 archetypeArtifactId 來決定的,因為這裡傳入的是 maven-archetype-webapp 如果我們傳入其他的就會建立不同的結構,預設值為 maven-archetype-quickstart ,有興趣的讀者可以參考更詳細的列表 ,我把部分常用的列表在這裡: 
Artifact Group Version Repository Description 
maven-archetype-j2ee-simple org.apache.maven.archetypes     A simple J2EE Java application 
maven-archetype-marmalade-mojo org.apache.maven.archetypes     A Maven plugin development project using marmalade 
maven-archetype-plugin org.apache.maven.archetypes     A Maven Java plugin development project 
maven-archetype-portlet org.apache.maven.archetypes     A simple portlet application 
maven-archetype-profiles org.apache.maven.archetypes     
maven-archetype-quickstart org.apache.maven.archetypes     
maven-archetype-simple org.apache.maven.archetypes     
maven-archetype-site-simple org.apache.maven.archetypes     A simple site generation project 
maven-archetype-site org.apache.maven.archetypes     A more complex site project 
maven-archetype-webapp org.apache.maven.archetypes     A simple Java web application 
maven-archetype-har net.sf.maven-har 0.9   Hibernate Archive 
maven-archetype-sar net.sf.maven-sar 0.9   JBoss Service Archive 

大家可以參考更詳細的 archetype:create 幫助 和 archtype參考資訊 。 
3.3 maven的多專案管理 

多專案管理是maven的主要特色之一,對於一個大型工程,用maven來管理他們之間複雜的依賴關係,是再好不過了。maven的專案配置之間的關係有兩種:繼承關係和引用關係。 
maven預設根據目錄結構來設定pom的繼承關係,即下級目錄的pom預設繼承上級目錄的pom。要設定兩者之間的關係很簡單,上級pom如下設定: 
<modules> 
    <module>ABCCommon</module> 
    <module>ABCCore</module> 
    <module>ABCTools</module> 
</modules> 

要記住的是,這裡的module是目錄名,不是子工程的artifactId。子工程如下設定: 

<parent> 
    <groupId>com.abc.product1</groupId> 
    <artifactId>abc-product1</artifactId> 
    <version>1.0.0-SNAPSHOT</version> 
</parent> 
<artifactId>abc-my-module2</artifactId> 
<packaging>jar</packaging> 

這樣兩者就相互關聯起來了,繼承關係就設定完畢,所有父工程的配置內容都會自動在子工程中生效,除非子工程有相同的配置覆蓋。如果你不喜歡層層遞進的目錄結構來實現繼承,也可以在parent中加入<relativePath>../a-parent/pom.xml</relativePath> 來制定parent專案的相對目錄。繼承關係通常用在專案共同特性的抽取上,通過抽取公共特性,可以大幅度減少子專案的配置工作量。 

引用關係是另外一種複用的方式,maven中配置引用關係也很簡單,加入一個 type 為 pom 的依賴即可。 
<dependency> 
    <groupId>org.sonatype.mavenbook</groupId> 
    <artifactId>persistence-deps</artifactId> 
    <version>1.0</version> 
    <type>pom</type> 
</dependency> 

但是無論是父專案還是引用專案,這些工程都必須用 mvn install 或者 mvn deploy 安裝到本地庫才行,否則會報告依賴沒有找到,eclipse編譯時候也會出錯。 

需要特別提出的是複用過程中,父專案的pom中可以定義 dependencyManagement 節點,其中存放依賴關係,但是這個依賴關係只是定義,不會真的產生效果,如果子專案想要使用這個依賴關係,可以在本身的 dependency 中新增一個簡化的引用 
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring</artifactId> 
</dependency> 

這種方法可以避免版本號滿天飛的情況。 
3.4 安裝庫檔案到maven庫中 

在maven中一般都會用到安裝庫檔案的功能,一則是我們常用的hibernate要使用jmx庫,但是因為sun的license限制,所以無法將其直接包含在repository中。所以我們使用mvn命令把jar安裝到我們本地的repository中 

mvn install:install-file -DgroupId=com.sun.jdmk -DartifactId=jmxtools -Dversion=1.2.1 -Dpackaging=jar -Dfile=/path/to/file 

如果我們想把它安裝到公司的repository中,需要使用命令 

mvn deploy:deploy-file -DgroupId=com.sun.jdmk -DartifactId=jmxtools -Dversion=1.2.1 -Dpackaging=jar -Dfile=/path/to/file -Durl=http://xxx.ss.com/sss.xxx -DrepositoryId=release-repo 

對於我們的工程輸出,如果需要放置到公司的repository中的話,可以通過配置pom來實現 
<distributionManagement> 
    <repository> 
        <id>mycompany-repository</id> 
        <name>MyCompany Repository</name> 
        <url>scp://repository.mycompany.com/repository/maven2</url> 
    </repository> 
</distributionManagement> 

這裡使用的scp方式提交庫檔案,還有其他方式可以使用,請參考faq部分。然後記得在你的settings.xml中加入這一內容 

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
          http://maven.apache.org/xsd/settings-1.0.0.xsd"> 
    ... 
    <servers> 
        <server> 
            <id>mycompany-repository</id> 
            <username>jvanzyl</username> 
            <!-- Default value is ~/.ssh/id_dsa --> 
            <privateKey>/path/to/identity</privateKey> 
            <passphrase>my_key_passphrase</passphrase> 
        </server> 
    </servers> 
    ... 
</settings> 
        


3.5 maven的變數 

maven定義了很多變數屬性,參考這裡 http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide 

    內建屬性 
        ${basedir } represents the directory containing pom.xml 
        ${version } equivalent to ${project.version } or ${pom.version } 
    Pom/Project properties 
    所有pom中的元素都可以用 project. 字首進行引用,以下是部分常用的 
        ${project.build.directory } results in the path to your "target" dir, this is the same as ${pom.project.build.directory } 
        ${project.build. outputD irectory } results in the path to your "target/classes" dir 
        ${project.name } refers to the name of the project. 
        ${project.version } refers to the version of the project. 
        ${project.build.finalName } refers to the final name of the file created when the built project is packaged 
    本地使用者設定 
    所有用的的 settings.xml 中的設定都可以通過 settings. 字首進行引用 
        ${settings.localRepository } refers to the path of the user's local repository. 
        ${maven.repo.local } also works for backward compatibility with maven1 ?? 
    環境變數 
    系統的環境變數通過 env. 字首引用 
        ${env.M2_HOME } returns the Maven2 installation path. 
        ${java.home } specifies the path to the current JRE_HOME environment use with relative paths to get for example: 
        <jvm>${java.home}../bin/java.exe</jvm> 
    java系統屬性 
    所有JVM中定義的java系統屬性. 
    使用者在pom中定義的自定義屬性 
    <project> 
        ... 
        <properties> 
            <my.filter.value>hello</my.filter.value> 
        </properties> 
        ... 
    </project> 
    則引用 ${my.filter.value } 就會得到值 hello 
    上級工程的變數 
    上級工程的pom中的變數用字首 ${project.parent } 引用. 上級工程的版本也可以這樣引用:${parent.version }. 

3.6 maven的使用 

我們已經知道maven預定義了許多的階段(phase),每個外掛都依附於這些階段,並且在進入某個階段的時候,呼叫執行這些相關外掛的功能。我們先來看完整的maven生命週期: 
生命週期 階段描述 
validate 驗證專案是否正確,以及所有為了完整構建必要的資訊是否可用 
generate-sources 生成所有需要包含在編譯過程中的原始碼 
process-sources 處理原始碼,比如過濾一些值 
generate-resources 生成所有需要包含在打包過程中的資原始檔 
process-resources 複製並處理資原始檔至目標目錄,準備打包 
compile 編譯專案的原始碼 
process-classes 後處理編譯生成的檔案,例如對Java類進行位元組碼增強(bytecode enhancement) 
generate-test-sources 生成所有包含在測試編譯過程中的測試原始碼 
process-test-sources 處理測試原始碼,比如過濾一些值 
generate-test-resources 生成測試需要的資原始檔 
process-test-resources 複製並處理測試資原始檔至測試目標目錄 
test-compile 編譯測試原始碼至測試目標目錄 
test 使用合適的單元測試框架執行測試。這些測試應該不需要程式碼被打包或釋出 
prepare-package 在真正的打包之前,執行一些準備打包必要的操作。這通常會產生一個包的展開的處理過的版本(將會在Maven 2.1+中實現) 
package 將編譯好的程式碼打包成可分發的格式,如JAR,WAR,或者EAR 
pre-integration-test 執行一些在整合測試執行之前需要的動作。如建立整合測試需要的環境 
integration-test 如果有必要的話,處理包併發布至整合測試可以執行的環境 
post-integration-test 執行一些在整合測試執行之後需要的動作。如清理整合測試環境。 
verify 執行所有檢查,驗證包是有效的,符合質量規範 
install 安裝包至本地倉庫,以備本地的其它專案作為依賴使用 
deploy 複製最終的包至遠端倉庫,共享給其它開發人員和專案(通常和一次正式的釋出相關) 

maven核心的外掛列表可以參考 http://maven.apache.org/plugins/index.html 。這裡僅列舉幾個常用的外掛及其配置引數: 

    clean外掛 
    只包含一個goal叫做 clean:clean ,負責清理構建時候建立的檔案。 預設清理的位置是如下幾個變數指定的路徑 project.build.directory, project.build.outputDirectory, project.build.testOutputDirectory, and project.reporting.outputDirectory 。 
    compiler外掛 
    包含2個goal,分別是 compiler:compile 和 compiler:testCompile 。可以到這裡檢視兩者的具體引數設定:compile , testCompile 。 
    surefire外掛 
    執行單元測試用例的外掛,並且能夠生成報表。包含一個goal為 surefire:test 。主要引數testSourceDirectory用來指定測試用例目錄,參考完整用法幫助 
    jar 
    負責將工程輸出打包到jar檔案中。包含兩個goal,分別是 jar:jar , jar:test-jar 。兩個goal負責從classesDirectory或testClassesDirectory中獲取所有資源,然後輸出jar檔案到outputDirectory中。 
    war 
    負責打包成war檔案。常用goal有 war:war ,負責從warSourceDirectory(預設${basedir}/src/main/webapp)打包所有資源到outputDirectory中。 
    resources 
    負責複製各種資原始檔,常用goal有 resources:resources ,負責將資原始檔複製到outputDirectory中,預設為${project.build.outputDirectory}。 
    install 
    負責將專案輸出(install:install)或者某個指定的檔案(install:install-file)加入到本機庫%USERPROFILE%/.m2/repository中。可以用 install:help 尋求幫助。 
    deploy 
    負責將專案輸出(deploy:deploy)或者某個指定的檔案(deploy:deploy-file)加入到公司庫中。 
    site 
    將工程所有文件生成網站,生成的網站介面預設和apache的專案站點類似,但是其文件用doxia格式寫的,目前不支援docbook,需要用其他外掛配合才能支援。需要指出的是,在maven 2.x系列中和maven3.x的site命令處理是不同的,在舊版本中,用 mvn site 命令可以生成reporting節點中的所有報表,但是在maven3中,reporting過時了,要把這些內容作為 maven-site-plugin的configuration的內容才行。詳細內容可以參考http://www.wakaleo.com/blog/292-site-generation-in-maven-3 

4. maven的使用問答 

除了以下的幾個faq條目之外,還有一些faq可以參考 

    maven 自己的FAQ 

兄弟們如果有其他問題,歡迎跟帖提問! 
4.1 依賴關係 
1) 問:如何增加刪除一個依賴關係? 

答:直接在pom檔案中加入一個dependency節點,如果要刪除依賴,把對應的dependency節點刪除即可。 
2) 問:如何遮蔽一個依賴關係?比如專案中使用的libA依賴某個庫的1.0版,libB以來某個庫的2.0版,現在想統一使用2.0版,如何去掉1.0版的依賴? 

答:設定exclusion即可。 
<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate</artifactId> 
    <version>3.2.5.ga</version> 
    <exclusions> 
        <exclusion> 
            <groupId>javax.transaction</groupId> 
            <artifactId>jta</artifactId> 
        </exclusion> 
    </exclusions> 
</dependency> 
3) 問:我有一些jar檔案要依賴,但是我又不想把這些jar去install到mvn的repository中去,怎麼做配置? 

答:加入一個特殊的依賴關係,使用system型別,如下: 
<dependency> 
    <groupId>com.abc</groupId> 
    <artifactId>my-tools</artifactId> 
    <version>2.5.0</version> 
    <type>jar</type> 
    <scope>system</scope> 
    <systemPath>${basedir}/lib/mylib1.jar</systemPath> 
</dependency> 

但是要記住,釋出的時候不會複製這個jar。需要手工配置,而且其他project依賴這個project的時候,會報告警告。如果沒有特殊要求,建議直接註冊釋出到repository。 

4) 問:在eclipse環境中同時使用maven builder和eclipse builder,並且設定專案依賴關係之後,為什麼編譯會出現artifact找不到錯誤,但是直接使用命令列mvn構建則一切正常? 

答:在project屬性中去掉java build path中對其他 project 的依賴關係,直接在pom中設定依賴關係即可 
<!-- 依賴的其他專案 --> 
<dependency> 
    <groupId>com.abc.project1</groupId> 
    <artifactId>abc-project1-common</artifactId> 
    <version>${project.version}</version> 
</dependency> 
另外,保證沒有其他錯誤。 
5) 問:我想讓輸出的jar包自動包含所有的依賴 

答:使用 assembly 外掛即可。 
<plugin> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <configuration> 
        <descriptorRefs> 
            <descriptorRef>jar-with-dependencies</descriptorRef> 
        </descriptorRefs> 
    </configuration> 
</plugin> 



6) 問:我的測試用例依賴於其他工程的測試用例,如何設定? 

答:maven本身在釋出的時候,可以釋出單純的jar,也可以同時釋出xxx-tests.jar和xxx-javadoc.jar(大家經常在repository中可以看到類似的東西)。我們自己的專案A要同時輸出test.jar可以做如下的設定 
<!-- 用於把test程式碼也做成一個jar --> 
<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-jar-plugin</artifactId> 
    <executions> 
        <execution> 
            <goals> 
                <goal>test-jar</goal> 
            </goals> 
        </execution> 
    </executions> 
</plugin> 
然後在其他需要引用的工程B中做如下的dependency設定 

<dependency> 
    <groupId>com.abc.XXX</groupId> 
    <artifactId>工程A</artifactId> 
    <version>${project.version}</version> 
    <type>test-jar</type> 
    <scope>test</scope> 
</dependency> 
7)如何讓maven將工程依賴的jar複製到WEB-INF/lib目錄下? 


8)我剛剛更新了一下我的nexus庫,但是我無法在eclipse中用m2eclipse找到我新增的庫檔案 

修改pom.xml檔案,將舊版jar的依賴內容中的版本直接修改為新版本即可。 


9)我要的jar最新版不在maven的中央庫中,我怎麼辦? 

將依賴的檔案安裝到本地庫,用如下命令可以完成: 

mvn install:install-file 
  -Dfile=<path-to-file> 
  -DgroupId=<group-id> 
  -DartifactId=<artifact-id> 
  -Dversion=<version> 
  -Dpackaging=<packaging> 
  -DgeneratePom=true 

Where: <path-to-file>  the path to the file to load 
       <group-id>      the group that the file should be registered under 
       <artifact-id>   the artifact name for the file 
       <version>       the version of the file 
       <packaging>     the packaging of the file e.g. jar     

10) 
4.2 變數 
1) 問:如何使用變數替換?專案中的某個配置檔案比如jdbc.properties使用了一些pom中的變數,如何在釋出中使用包含真實內容的最終結果檔案? 

答:使用資源過濾功能,比如: 
<project> 
    ... 
    <properties> 
        <jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName> 
        <jdbc.url>jdbc:mysql://localhost:3306/development_db</jdbc.url> 
        <jdbc.username>dev_user</jdbc.username> 
        <jdbc.password>s3cr3tw0rd</jdbc.password> 
    </properties> 
    ... 
    <build> 
        <resources> 
            <resource> 
                <directory>src/main/resources</directory> 
                <filtering>true</filtering> 
            </resource> 
        </resources> 
    </build> 
    ... 
    <profiles> 
        <profile> 
            <id>production</id> 
            <properties> 
                <jdbc.driverClassName>oracle.jdbc.driver.OracleDriver</jdbc.driverClassName> 
                <jdbc.url>jdbc:oracle:thin:@proddb01:1521:PROD</jdbc.url> 
                <jdbc.username>prod_user</jdbc.username> 
                <jdbc.password>s00p3rs3cr3t</jdbc.password> 
            </properties> 
        </profile> 
    </profiles> 
</project> 
2) 問: maven-svn-revision-number-plugin 外掛說明 

答: maven-svn-revision-number-plugin 可以從 SVN 中獲取版本號,並將其變成環境變數,交由其他外掛或者profile使用,詳細幫助在這裡 。一般和resource的filter機制同時使用 
<plugins> 
    <plugin> 
        <groupId>com.google.code.maven-svn-revision-number-plugin</groupId> 
        <artifactId>maven-svn-revision-number-plugin</artifactId> 
        <version>1.3</version> 
        <executions> 
            <execution> 
                <goals> 
                    <goal>revision</goal> 
                </goals> 
            </execution> 
        </executions> 
        <configuration> 
            <entries> 
                <entry> 
                    <prefix>prefix</prefix> 
                </entry> 
            </entries> 
        </configuration> 
    </plugin> 
</plugins> 

這段程式碼負責把resource檔案中的內容替換成適當內容 
repository = ${prefix.repository} 
path = ${prefix.path} 
revision = ${prefix.revision} 
mixedRevisions = ${prefix.mixedRevisions} 
committedRevision = ${prefix.committedRevision} 
status = ${prefix.status} 
specialStatus = ${prefix.specialStatus} 
3)我的程式有些單元測試有錯誤,如何忽略測試步驟? 

有好幾種方法都可以實現跳過單元測試步驟,一種是給mvn增加命令列引數 -Dmaven.test.skip=true 或者 -DskipTests=true ;另外一種是給surefire外掛增加引數,如下: 

<project> 
  [...] 
  <build> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-surefire-plugin</artifactId> 
        <version>2.8</version> 
        <configuration> 
          <skipTests>true</skipTests> 
        </configuration> 
      </plugin> 
    </plugins> 
  </build> 
  [...] 
</project> 

4) 如果只想執行單個測試用例,能否實現? 

可以,執行時候增加命令列引數 -Dtest=MyTest 即可,其中MyTest是所需要執行的單元測試用例名稱,但是不需要包含package部分。 
4.3 編譯 
1) 問:如何給外掛指派引數?比如我要設定一些編譯引數 

答:以下內容設定編譯器編譯java1.5的程式碼 
<project> 
    ... 
    <build> 
        ... 
        <plugins> 
            <plugin> 
                <artifactId>maven-compiler-plugin</artifactId> 
                <configuration> 
                    <source>1.5</source> 
                    <target>1.5</target> 
                </configuration> 
            </plugin> 
        </plugins> 
        ... 
    </build> 
    ... 
</project> 
要設定其他外掛的引數也可以,請參考對應外掛的幫助資訊 
2) 問:我的目錄是非標準的目錄結構,如何設定讓maven支援? 

答:指定source目錄和test-source目錄即可。 
<build> 
    <directory>target</directory> 
    <sourceDirectory>src</sourceDirectory> 
    <scriptSourceDirectory>js/scripts</scriptSourceDirectory> 
    <testSourceDirectory>test</testSourceDirectory> 
    <outputDirectory>bin</outputDirectory> 
    <testOutputDirectory>bin</testOutputDirectory> 
</build> 
這個例子把原始碼設定成了src目錄,測試程式碼在test目錄,所以輸出到bin目錄。這裡要注意,directory如果也設定成bin目錄的話,maven打包的時候會引起死迴圈,因為directory是所有工作存放的地方,預設包含outputDirectory定義的目錄在內。 
3) 我原始碼是UTF8格式的,我如何在maven中指定? 

設定一個變數即可 
<project> 
    ... 
    <properties> 
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 
    ... 
</project> 
{color:blue}以上是官方給出的解決方案,但是經過嘗試這樣只能影響到resource處理時候的編碼{color},真正有用的是如下配置: 

{code:xml} 
<build> 
  ... 
    <plugin> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <configuration> 
        <encoding>UTF-8</encoding> 
      </configuration> 
    </plugin> 
  ... 
</build> 
{code} 

. 問:我的專案除了main/java目錄之外,還加了其他的c++目錄,想要一併編譯,如何做? 
答:使用native外掛,具體配置方法參考[http://mojo.codehaus.org/maven-native/native-maven-plugin/] 

{code:xml} 
<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>native-maven-plugin</artifactId> 
    <extensions>true</extensions> 
    <configuration> 
</plugin>    
{code} 

. 問:我想要把工程的所有依賴的jar都一起打包,怎麼辦? 
答:首先修改maven的配置檔案,給maven-assembly-plugin增加一個jar-with-dependencies的描述。 

{code:xml} 
<project> 
  [...] 
  <build> 
    <plugins> 
      <plugin> 
        <artifactId>maven-assembly-plugin</artifactId> 
        <configuration> 
          <descriptorRefs> 
            <descriptorRef>jar-with-dependencies</descriptorRef> 
          </descriptorRefs> 
        </configuration> 
      </plugin> 
    </plugins> 
  </build> 
  [...] 
</project> 
{code} 

然後使用命令打包即可: 

mvn assembly:assembly 

. 問:我想把main/scripts中的內容一起打包釋出,如何做? 
答:在pom中配置額外的資源目錄。如果需要的話,還可以指定資源目錄的輸出位置 

{code:xml} 
<build> 
  ... 
  <resources> 
    <resource> 
      <filtering>true</filtering> 
      <directory>src/main/command</directory> 
      <includes> 
        <include>run.bat</include> 
        <include>run.sh</include> 
      </includes> 
      <targetPath>/abc</targetPath> 
    </resource> 
    <resource> 
      <directory>src/main/scripts</directory> 
    </resource> 
  </resources> 
  ... 
</build> 
{code} 

. 問:我有多個原始碼目錄,但是maven只支援一個main src和一個test src,怎麼辦? 
答:使用另外一個外掛,並仿照如下配置pom 

{code:xml} 
<plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>build-helper-maven-plugin</artifactId> 
        <version>1.1</version> 
        <executions> 
          <execution> 
            <id>add-source</id> 
            <phase>generate-sources</phase> 
            <goals> 
              <goal>add-source</goal> 
            </goals> 
            <configuration> 
              <sources> 
                <source>src/config/java</source> 
                <source>src/main/java</source> 
                <source>src/member/java</source> 
              </sources> 
            </configuration> 
          </execution> 
        </executions> 
      </plugin> 
{code} 

. 問:我的原始碼目錄中有一部分檔案我不想讓maven編譯,怎麼做? 
答:使用一個maven外掛,然後使用includes和excludes。同理,也可以處理資源的過濾。 

{code:xml} 
<build> 
  <sourceDirectory>http://www.cnblogs.com/src/java</sourceDirectory> 
  <plugins> 
    <plugin> 
      <groupId>com.sun.enterprise</groupId> 
      <artifactId>hk2-maven-plugin</artifactId> 
      <configuration> 
        <includes> 
          <include>com/sun/logging/LogDomains.*</include> 
          <include>com/sun/enterprise/util/OS.java</include> 
          <include>com/sun/enterprise/util/io/FileUtils.java</include> 
          <include>com/sun/enterprise/util/zip/**</include> 
          <include>com/sun/enterprise/util/i18n/**</include> 
          <include>com/sun/enterprise/deployment/backend/IASDeploymentException.java</include> 
        </includes> 
        <excludes> 
          <exclude>com/sun/enterprise/config/ConfigBeansFactory.java</exclude> 
          <exclude>com/sun/enterprise/config/clientbeans/**</exclude> 
        </excludes> 
      </configuration> 
    </plugin> 
  </plugins> 
  <resources> 
    <resource> 
      <directory>http://www.cnblogs.com/src/java</directory> 
      <includes> 
        <include>**/*.properties</include> 
      </includes> 
    </resource> 
  </resources> 
</build> 
{code} 

. 問:我的專案是一個純的html組成的專案,沒有任何的java程式碼,怎麼跳過編譯過程? 
答:配置如下 

{code:xml} 
<build> 
  <sourceDirectory>src/java</sourceDirectory> 
  <plugins> 
    <plugin> 
    <groupId>com.sun.enterprise</groupId> 
    <artifactId>hk2-maven-plugin</artifactId> 
    </plugin> 
  </plugins> 
</build> 
{code} 

. 問:我的工程裡用hibernate,想在編譯時候自動生成ddl,如何做? 
答:新增外掛 

hibernate3-maven-plugin 

,按照如下配置: 

{code:xml} 
        <plugin> 
          <groupId>org.codehaus.mojo</groupId> 
          <artifactId>hibernate3-maven-plugin</artifactId> 
          <version>2.1</version> 
          <configuration> 
            <components> 
              <component> 
                <name>hbm2ddl</name> 
                <implementation>annotationconfiguration</implementation> 
              </component> 
            </components> 
          </configuration> 
          <dependencies> 
            <dependency> 
              <groupId>hsqldb</groupId> 
              <artifactId>hsqldb</artifactId> 
              <version>${hsqldb.version}</version> 
            </dependency> 
          </dependencies> 
        </plugin> 
{code} 

. 問:我能用maven支援eclipse RCP專案嗎? 

答:當然可以,你可以使用外掛 Tycho,詳細內容可以參考這裡[http://mattiasholmqvist.se/2010/02/building-with-tycho-part-1-osgi-bundles/]. 

<plugin> 
  <groupid>org.sonatype.tycho</groupid> 
  <artifactid>target-platform-configuration</artifactid> 
  <version>0.7.0</version> 
  <configuration> 
    <resolver>p2</resolver> 
  </configuration> 
</plugin> 
另外,老牌的pde-maven-plugin就不要用了,已經好幾年沒見更新了。 

4.4 ant互動 
1) 如何在maven編譯時候執行ant指令碼? 

使用專門的antrun外掛,並且在target標籤內部加入ant的程式碼 

      <plugin> 
        <artifactId>maven-antrun-plugin</artifactId> 
        <version>1.6</version> 
        <executions> 
          <execution> 
            <phase> <!-- 生命週期階段 --> </phase> 
            <configuration> 
              <target> 
                <!-- 加入target內部的程式碼 --> 
              </target> 
            </configuration> 
            <goals> 
              <goal>run</goal> 
            </goals> 
          </execution> 
        </executions> 
      </plugin> 

2)如何在ant指令碼中引用maven的classpath? 

maven給每一個依賴都生成了一個屬性,格式為"groupId:artifactId[:classifier]:type",比如,如果一下例子就顯示依賴的org.apache.common-util的jar檔案路徑 

<echo message="Dependency JAR Path: ${org.apache:common-util:jar}"/> 

另外,maven還預定義了四個classpath的引用,他們是 

    maven.compile.classpath 
    maven.runtime.classpath 
    maven.test.classpath 
    maven.plugin.classpath 

3)如何使用antrun外掛執行外部的build檔案? 

很簡單,直接在antrun裡邊使用ant指令即可,如下: 

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-antrun-plugin</artifactId> 
    <version>1.6</version> 
    <executions> 
        <execution> 
            <id>compile</id> 
            <phase>compile</phase> 
            <configuration> 
                <target> 
                    <!-- 同時傳遞內建的classpath給外部ant檔案 --> 
                    <property name="compile_classpath" refid="maven.compile.classpath"/> 
                    <property name="runtime_classpath" refid="maven.runtime.classpath"/> 
                    <property name="test_classpath" refid="maven.test.classpath"/> 
                    <property name="plugin_classpath" refid="maven.plugin.classpath"/> 
    
                    <ant antfile="${basedir}/build.xml"> 
                        <target name="test"/> 
                    </ant> 
                </target> 
            </configuration> 
            <goals> 
                <goal>run</goal> 
            </goals> 
        </execution> 
    </executions> 
</plugin> 

. 問:如何在ant中使用maven的功能? 
答:使用ant的[maven task|http://maven.apache.org/ant-tasks/index.html],不過只有ant 1.6以上和jdk 1.5環境才支援。 
h4. 測試相關 
. 問:如何忽略某個階段的結果?比如單元測試不一定要全正確 
答:給外掛增加testFailureIgnore引數,並設定為false。如果要遮蔽該階段,則用 

<skip>true</skip> 

{code:xml} 
<project> 
  [...] 
  <build> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-surefire-plugin</artifactId> 
        <configuration> 
          <testFailureIgnore>true</testFailureIgnore> 
        </configuration> 
      </plugin> 
    </plugins> 
  </build> 
  [...] 
</project> 
{code} 

. 問:我如何在maven中加入PMD,CheckStyle,JDepend等檢查功能? 
答:加入PMD檢查,以下程式碼如果在 

reporting 

節點中加入則在 

mvn site 

中執行,如果在 

build 

節點中加入,則在build的時候自動執行檢查。詳細配置參考[pmd外掛使用說明|http://maven.apache.org/plugins/maven-pmd-plugin/] 

{code:xml} 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-pmd-plugin</artifactId> 
        <version>2.5</version> 
      </plugin> 
    </plugins> 
{code} 

加入 checkstyle 檢查,詳細配置參考[checkstyle外掛使用說明|http://maven.apache.org/plugins/maven-checkstyle-plugin/],同樣注意放置在reporting和build節點中的區別(所有報表類外掛都要同樣注意): 

{code:xml} 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-checkstyle-plugin</artifactId> 
        <version>2.5</version> 
      </plugin> 
{code} 

加入 simian 的支援,simian是一個支援程式碼相似度檢查的工具,目前有maven外掛,也有checkstyle的外掛。它不僅可以檢查java,甚至可以支援文字檔案的檢查。詳細幫助資訊參考[這裡|http://www.redhillconsulting.com.au/products/simian/]。simian 的 maven外掛在[這裡|http://mojo.codehaus.org/simian-report-maven-plugin/introduction.html] 

{code:xml} 
      <build> 
         <plugins> 
            <plugin> 
               <groupId>org.codehaus.mojo</groupId> 
               <artifactId>simian-maven-plugin</artifactId> 
               <version>1.6.1</version> 
            </plugin> 
         </plugins> 
         ... 
      </build> 
{code} 

加入 jdepend 檢查,詳細配置參考[jdepend使用說明|http://mojo.codehaus.org/jdepend-maven-plugin/], 

{code:xml} 
      <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>jdepend-maven-plugin</artifactId> 
        <version>2.0-beta-2</version> 
      </plugin> 
{code} 

加入 findbugz 檢查,詳細配置參考[findbugz使用說明|http://mojo.codehaus.org/findbugs-maven-plugin/usage.html], 

{code:xml} 
      <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>findbugs-maven-plugin</artifactId> 
        <version>2.0.1</version> 
      </plugin> 
{code} 

加入javadoc生成,詳細配置參考[javadoc usage|http://maven.apache.org/plugins/maven-javadoc-plugin/usage.html] 

{code:xml} 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-javadoc-plugin</artifactId> 
        <version>2.7</version> 
        <configuration> 
          ... 
        </configuration> 
      </plugin> 
{code} 

加入 jxr 支援,JXR是一個生成java程式碼交叉引用和原始碼的html格式的工具,詳細配置資訊參考[jxr usage|http://maven.apache.org/plugins/maven-jxr-plugin/]。注意,jxr沒有必要在build階段執行。 

{code:xml} 
  <reporting> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-jxr-plugin</artifactId> 
        <version>2.1</version> 
      </plugin> 
    </plugins> 
  </reporting> 
{code} 

加入 Cobertura 支援,它是一個程式碼覆蓋率工具,可以用來評估具有相應測試的原始碼的比率。詳細幫助在[這裡|http://mojo.codehaus.org/cobertura-maven-plugin/index.html]。另外一個功能相似的軟體是[EMMA|http://emma.sourceforge.net/samples.html],詳細的幫助在[這裡|http://mojo.codehaus.org/emma-maven-plugin/usage.html]。兩個產品的比較文章在[這裡|http://www.topcoder.com/tc?module=Static&d1=features&d2=030107],個人傾向於都要用,因為給出的指標不一樣,都有參考作用。 

{code:xml|title=Cobertura } 
      <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>cobertura-maven-plugin</artifactId> 
        <version>2.4</version> 
        <configuration> 
          <check> 
            <branchRate>85</branchRate> 
            <lineRate>85</lineRate> 
            <haltOnFailure>true</haltOnFailure> 
            <totalBranchRate>85</totalBranchRate> 
            <totalLineRate>85</totalLineRate> 
            <packageLineRate>85</packageLineRate> 
            <packageBranchRate>85</packageBranchRate> 
            <regexes> 
              <regex> 
                <pattern>com.example.reallyimportant.*</pattern> 
                <branchRate>90</branchRate> 
                <lineRate>80</lineRate> 
              </regex> 
              <regex> 
                <pattern>com.example.boringcode.*</pattern> 
                <branchRate>40</branchRate> 
                <lineRate>30</lineRate> 
              </regex> 
            </regexes> 
          </check> 
        </configuration> 
        <executions> 
          <execution> 
            <goals> 
              <goal>clean</goal> 
              <goal>check</goal> 
            </goals> 
          </execution> 
        </executions> 
      </plugin> 
{code} 

{code:xml|title=EMMA} 
  <reporting> 
    ... 
    <plugins> 
      ... 
      <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>emma-maven-plugin</artifactId> 
        <version>1.0-alpha-3-SNAPSHOT</version> 
      </plugin> 
      ... 
    </plugins> 
    ... 
  </reporting> 
{code} 

新增 javaNCSS 外掛,它是一個java程式碼的度量工具,詳細參考在[這裡|http://mojo.codehaus.org/javancss-maven-plugin/]。 

{code:xml} 
  <reporting> 
    <plugins> 
      <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>javancss-maven-plugin</artifactId> 
        <version>2.0-beta-2</version> 
      </plugin> 
    </plugins> 
  </reporting> 
{code} 

h4. profile相關 
. 問:profile能夠設定為某個變數不存在的條件下啟用? 
答:使用!字首,請看示例: 

{code:xml} 
<activation> 
        <property> 
          <name>!environment.type</name> 
        </property> 
      </activation> 
{code} 

h4. 部署相關 
. 問:其他部署到伺服器的方式和配置怎麼配? 
答:本文摘自 [http://blog.csdn.net/zyxnetxz/archive/2009/05/18/4199348.aspx]{panel} *Distribution Management* 用於配置分發管理,配置相應的產品釋出資訊,主要用於釋出,在執行mvn deploy後表示要釋出的位置 *# 配置到檔案系統 

{code:xml} 
<distributionManagement> 
  <repository> 
    <id>proficio-repository<id> 
    <name>Proficio Repository<name> 
    <url>file://${basedir}/target/deploy<url> 
  <repository> 
<distributionManagement> 
{code} 

*# 使用ssh2配置 

{code:xml} 
<distributionManagement> 
  <repository> 
    <id>proficio-repository<id> 
    <name>Proficio Repository<name> 
    <url>scp://sshserver.yourcompany.com/deploy<url> 
  <repository> 
<distributionManagement> 
{code} 

*# 使用sftp配置 

{code:xml} 
<distributionManagement> 
  <repository> 
    <id>proficio-repositoryi<d> 
    <name>Proficio Repository<name> 
    <url>sftp://ftpserver.yourcompany.com/deploy<url> 
  <repository> 
<distributionManagement> 
{code} 

*# 使用外在的ssh配置編譯擴充套件用於指定使用wagon外在ssh提供,用於提供你的檔案到相應的遠端伺服器。 

{code:xml} 
<distributionManagement> 
  <repository> 
    <id>proficio-repository<id> 
    <name>Proficio Repository<name> 
    <url>scpexe://sshserver.yourcompany.com/deploy<url> 
  <repository> 
<distributionManagement> 
<build> 
  <extensions> 
    <extension> 
      <groupId>org.apache.maven.wagon<groupId> 
      <artifactId>wagon-ssh-external<artifactId> 
      <version>1.0-alpha-6<version> 
    <extension> 
  <extensions> 
<build> 
{code} 

*# 使用ftp配置 

{code:xml} 
<distributionManagement> 
  <repository> 
    <id>proficio-repository<id> 
    <name>Proficio Repository<name> 
    <url>ftp://ftpserver.yourcompany.com/deploy<url> 
  <repository> 
<distributionManagement> 
<build> 
  <extensions> 
    <extension> 
      <groupId>org.apache.maven.wagongroupId> 
      <artifactId>wagon-ftpartifactId> 
      <version>1.0-alpha-6version> 
    <extension> 
  <extensions> 
<build> 
{code} 

{panel} h4. 外掛配置 
. 問:我用maven輸出site,如何設定輸出為utf8編碼? 
答: 配置site外掛的編碼設定 

{code:xml} 
... 
  <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-site-plugin</artifactId> 
    <version>2.0-beta-6</version> 
    <configuration> 
      <outputEncoding>UTF-8</outputEncoding> 
    </configuration> 
  </plugin> 
  ... 
{code}

相關文章