<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Terry.Li-彬

    虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks

    級別: 中級

    Sing Li (westmakaha@yahoo.com), 作家, Wrox Press

    2007 年 1 月 08 日

    現代軟件項目不再是單個本地團隊獨立開發的產物。隨著健壯的企業級開源組件的可用性日益提高,當今的軟件項目需要項目團隊間的動態協作,往往也需要混合使用在全球范圍內創建和維護的組件。如今,Apache Maven 構建系統步入了第二代,它和由 Internet 帶來的全球軟件開發時代之前所創建的那些遺留構建工具不同,它完全是重新設計的,以應對這些現代的挑戰。本教程將帶您從頭領略 Maven 2。

    開始之前

    現代軟件開發基于健壯的企業級開源技術,它需要一類新的構建工具和項目協作工具。Apache Maven 2 的核心引擎旨在簡化往往十分復雜的大型協作性軟件項目的構建和管理。在大型項目團隊環境中工作是種挑戰,而 Maven 2 以友好為設計目的,即便對那些不熟悉這種挑戰的開發人員而言,Maven 2 也足夠友好。本教程首先圍繞單個的新手開發展開,然后逐漸介紹 Maven 2 中的一些協作性的概念和功能。我們鼓勵您在本教程提供的介紹之上,探究本文范圍之外的 Maven 2 的一些高級功能。

    關于本教程

    本教程將循序漸進地向您介紹有關 Maven 2 的基礎概念和實踐練習,具體內容包括:

    • Maven 2 概覽
    • 理解 Maven 2 依賴項管理模型
    • Maven 2 存儲庫和 Maven 2 坐標
    • Maven 2 生命周期、階段、插件和 mojo
    • 下載和安裝 Maven 2
    • 實踐 Maven 2 —— 您的第一個 Maven 2 項目
    • 定制項目對象模型(POM)
    • 參與多個項目
    • 實踐 Maven 2 —— 參與多個項目構建
    • 在 Eclipse 3.2 中安裝 Maven 2.x Plug-in
    • 在 Eclipse 3.2 中使用 Maven 2.x Plug-in

    讀完本教程,您會理解并欣賞 Maven 2 背后的設計理念。也將進一步熟悉在使用 Maven 2 構建的項目中工作所需的基本技能。這是一張通往 Apache 和 Codehaus 社區中大多數大型項目的通行證。最為重要的是,您將可以把 Maven 2 應用到日常的項目構建和管理活動中。





    回頁首


    先決條件

    您應當大體上熟悉 Java™ 開發。本教程假設您理解構建工具的價值和基本操作,包括依賴項管理和輸出打包。要求您能將 Eclipse 3.2 用作 IDE,從而在 Eclipse 中使用 Maven 2.x 插件。如果您熟悉大型開源項目(如 Apache 軟件基金會管理下的項目),那就太好了。理解 Java 5 編碼(包括泛型)會很有幫助。如果有各種項目構建技術的經驗(如 Ant、autoconfmakenmake)也很好,但不做強制性要求。





    回頁首


    系統需求

    為繼續學習和試驗本教程中的代碼,您需要有效安裝 (或其后的版本)或 IBM JDK 1.5.0 SR3

    針對教程中關于 Eclipse 的 Maven 2.x 的插件部分,需要有效安裝 Eclipse 3.2.1 或其后版本。

    本教程的推薦系統配置如下:

    • 支持上述 JDK/JRE 的系統,有至少 1GB 的主存
    • 有至少 20MB 的磁盤空間來安裝軟件組件和樣例

    本教程中的說明基于 Microsoft Windows 操作系統。教程中涵蓋的所有工具也可以在 Linux® 和 UNIX® 系統上運行。

    Maven 2 概覽

    Maven 是一個頂級的 Apache Software Foundation 開源項目,創建它最初是為了管理 Jakarta Turbine 項目復雜的構建過程。從那以后,不論是開源開發項目還是私有開發項目都選擇 Maven 作為項目構建系統。Maven 快速地發展著,如今已是第二版,Maven 已經從針對單個復雜項目的定制構建工具成長為廣泛使用的構建管理系統,其豐富的功能可以應用于大多數的軟件開發場景。

    概括來講,Maven 2 能夠:

    • 理解項目通常是如何構建的。

    • 利用其內嵌的項目知識簡化和便利項目構建。

    • 利用其內嵌的項目知識來幫助用戶理解復雜的項目結構和構建過程中潛在的變數。

    • 設計并實現一個經證實的依賴項管理系統,該系統順應了當今全球化和相互聯系的項目團隊的需求。

    • 利用其內部知識,針對簡單項目提供簡單的用戶體驗。

    • 對于高級用戶來說相當靈活;針對特別的應用場景,可以覆蓋其內嵌模型,也可以通過配置、部署元數據或創建自定義插件對其內嵌模型進行改寫。

    • 全面擴展現有行為之外的場景細節。

    • 捕獲新出現的最佳實踐和各個用戶社區間的經確認的共同性,并將它們納入到 Maven 的內嵌項目知識中,從而不斷地得到改進。

    Maven 2 —— 概念性的概覽

    為捕捉項目構建知識,Maven 2 依賴于一套發展中的有關事物如何運轉的概念性模型。部分模型被硬編碼為 Maven 代碼庫的一部分,這些模型通過新的 Maven 發布版本不斷得到精煉。圖 1 解釋了 Maven 2 的關鍵模型:



    圖 1. Maven 2 對象和操作模型
    Maven 2 對象和操作模型

    圖 1 中的關鍵組件為:

    • 項目對象模型(POM): POM 是 Maven 2 中的里程碑式的模型。該模型的一部分已經構建到 Maven 引擎(被親切地稱為反應堆 )中,其余部分則通過一個名叫 pom.xml 的基于 XML 的元數據文件來聲明。

    • 依賴項管理模型: Maven 對如何管理項目的依賴項很在行。依賴項管理是一片灰色地帶,典型的構建-管理工具和系統都未明確涉及。Maven 2 構建了 Maven 依賴項管理模型,該模型能夠適應大多數需求。這個模型被證明是有效而高產的模型,目前,主要的開源項目都部署了該模型。

    • 構建生命周期和階段:和 POM 相關的概念是構建生命周期階段。這是 Maven 2 的內嵌概念模型和現實物理世界之間的接口。使用 Maven 時,工作主要是通過插件來執行的。在構建周期中,Maven 2 通過遵循一系列定義好的階段,將這些插件協調起來。

    如果您對其中一些概念還有點模糊,請不要擔心。接下來的部分會用具體的例子來鞏固這些模型背后的概念。





    回頁首


    Maven 2 —— 物理概覽

    圖 2 揭示了 Maven 2 的操作方式和與之交互的方式,同時顯示了它的物理構成。圖 2 提供了有關如何與 Maven 進行交互的概覽:



    圖 2. Maven 2 操作和交互模型
    Maven 2 操作和交互模型

    圖 2 中,POM 是 Maven 對您的特定項目的理解。這個模型由包含在一系列 pom.xml 文件中的聲明性描述構成。這些 pom.xml 文件構成一棵樹,每個文件能從其父文件中繼承屬性。Maven 2 提供一個 Super POM。這個 Super POM 位于層級樹的頂端,它包含所有項目的默認通用屬性;每個項目的 POM 都從這個 Super POM 處繼承。

    依賴項被指定為 pom.xml 文件的一部分。Maven 根據其依賴項管理模型解析項目依賴項。Maven 2 在本地存儲庫和全球存儲庫尋找依賴性組件(在 Maven 術語里稱作工件 )。在遠程存儲庫中解析的工件被下載到本地存儲庫中,以便使接下來的訪問可以有效進行。Maven 2 中的這個依賴項解析器可以處理可遞 依賴項。即,它能有效地解析您的依賴項所依賴的那些依賴項。

    Maven 引擎通過插件 親自執行幾乎所有的文件處理任務。插件被配置和描述在 pom.xml 文件中。依賴項管理系統將插件當作工件來處理,并根據構建任務的需要來下載插件。每個插件都能和生命周期中的不同階段聯系起來。Maven 引擎有一個狀態機,它運行在生命周期的各個階段,在必要的時候調用插件。

    理解 Maven 2 依賴項管理模型

    在有效利用 Maven 2 之前,您需要理解 Maven 2 依賴項管理模型是如何運行的。

    依賴項開發適應于這樣的項目,其軟件組件(稱作模塊 )是由不同的項目團隊開發的。它支持持續獨立開發,也支持對所有依賴模塊進行精煉。

    這個團隊協作場景在通過 Internet 建立和維護的開源項目中十分常見,由于內部開發大受開源或外包世界的沖擊和影響,這種場景在合作開發的圈子里日益盛行。

    解析項目依賴項

    Maven 2 依賴項管理引擎幫助解析構建過程中的項目依賴項。

    Maven 本地存儲庫和遠程存儲庫

    Maven 2 本地存儲庫是磁盤上的一個目錄,通常位于 HomeDirectory/.m2/repository。這個庫扮演著高性能本地緩存的角色,存儲著在依賴項解析過程中下載的工件。遠程存儲庫要通過網絡訪問。可以在 settings.xml 配置文件中維護一個遠程存儲庫列表以備使用。

    實踐中,依賴項在 pom.xml 文件內的 <dependencies> 元素中指定,并作為 POM 的一部分注入到 Maven 中。

    項目依賴項存儲在存儲庫服務器(在 Maven 術語中簡單地稱之為存儲庫 )上。要成功的解析依賴項,需要從包含該工件的存儲庫里找到所需的依賴性工件。

    通過 settings.xml 配置 Maven

    可以在一個 settings.xml 文件中指定影響 Maven 操作的配置屬性。默認的設置文件是 MavenInstallationDirectory/conf/settings.xml。Maven 2 用戶可通過維護 UserHomeDirectory/.m2/settings.xml 來覆蓋一些配置屬性。參見 Maven 設置參考,獲取更多有關可配置設置的信息。

    基于 POM 中的項目依賴項信息,該依賴項解析器試圖以下列方式解析依賴項:

    1. 檢查本地存儲庫中的依賴項。
    2. 檢查遠程存儲庫列表中的依賴項。
    3. 如果前兩步失敗,則報告一個錯誤。

    默認情況下,第二步中所涉及的第一個遠程存儲庫是一個能在全球訪問的集中式 Maven 2 存儲庫,它包含了最流行的開源項目的一些工件。在內部開發中,可以設置額外的遠程存儲庫來包含從內部開發模塊中發布的工件。可以使用 settings.xml 中的 <repositories> 元素來配置這些額外的遠程存儲庫。





    回頁首


    確保單個的工件

    將 Maven 2 用于項目構建時,依賴項解析通過一個集中的存儲庫確保只存在一個依賴性工件,而不考慮有多少項目或子項目引用該工件。這是多模塊項目構建中一個重要的屬性,因為包含多個工件會導致一些項目一致性和集成方面的問題。

    存儲庫和坐標

    Maven 2 存儲庫存儲 Maven 在一個項目的依賴項解析中使用過的工件集。在本地磁盤上訪問本地存儲庫,通過網絡訪問遠程存儲庫。

    工件通常被打包成包含二進制庫或可執行庫的 JAR 文件。這被認為是工件的一個類型。但在實踐中,工件也可以是 WAR、EAR 或其他代碼捆綁類型。

    Maven 2 利用操作系統的目錄結構對存儲在存儲庫中的工件集進行快速索引。這個存儲庫索引系統依賴于這種能力來通過工件的坐標 惟一標識工件。

    Maven 坐標

    Maven 坐標是一組可以惟一標識工件的三元組值。坐標包含了下列三條信息:

    • 組 ID:代表制造該工件的實體或組織。例如,com.ibm.devworks 就是一個組 ID。

    • 工件 ID:實際的工件的名稱。例如,主體類名為 OpsImp 的項目也許會用 OpsImp 作為其工件 ID。

    • 版本:該工件的版本號。支持的格式為 mmm.nnn.bbb-qqqqqqq-dd ,其中, mmm 是主版本號, nnn 是次版本號, bbb 代表其 bug 修復水平。 qqqqq (限定詞)或 dd (構建號)也能添加到版本號中,這兩項是可選項。

    對 Maven 坐標的使用貫穿于 Maven 配置文件和 POM 文件中。例如,要在命名為 OpsImp 的模塊上指定項目依賴項(在 1.0-SNAPSHOT 級別),pom.xml 文件應包含清單 1 所示的部分:



    清單 1. OpsImp 樣例模塊的 Maven 坐標
                <dependencies>
    <dependency> <groupId>com.ibm.devworks</groupId> <artifactId>OpsImp</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>

    特別限定詞 SNAPSHOT 告訴 Maven 2:該項目或模塊還處于開發狀態中,它應該獲取最新版的可用工件。

    要將該項目指定為依賴于 JUnit 進行單元測試,可以將 JUnit 3.8.1 的坐標作為一個依賴項添加到該項目的 pom.xml 文件中,如清單 2 所示:



    清單 2. JUnit 依賴項的 Maven 坐標
                <dependencies>
    <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> </dependency> </dependencies>





    回頁首


    深入 Maven 存儲庫

    由于 Maven 存儲庫是普通的目錄樹,所以可以很容易地看到工件是如何存儲到磁盤上的。圖 3 是本地存儲庫的一部分,顯示了 JUnit 3.8.1 工件的位置:



    圖 3. Maven 2 存儲庫內幕
    Maven 2 存儲庫內幕

    從圖 3 中可以看出,Maven 維護了一個工件的 POM 文件,同時也為該工件和其存儲庫中的 POM 維護了檢驗和散列。當工件在存儲庫間轉移時,這些文件幫助確保工件的完整性。該工件已由 Maven 的依賴項管理引擎從中央存儲庫下載并放置到本地存儲庫中。

    在圖 4 中,坐標為 com.ibm.devworks/OpsImp/1.0-SNAPSHOT 的工件顯示在本地存儲庫中。該工件和 POM 文件一起存放在存儲庫。在本例中,該工件在本地安裝。



    圖 4. 本地存儲庫中的 OpsImp 工件
    本地存儲庫中的 OpsImp 工件 

    Maven 2 生命周期、階段、插件和 mojo

    Maven 通過插件動作完成大多數構建任務。可以把 Maven 引擎認為是插件動作的協調器。

    插件中的 Mojo

    插件是適應 Maven 的插件框架的軟件模塊。現在,可以使用 Java、Ant 或 Beanshell 來創建自定義插件。插件中的每個任務稱作一個 mojo。有時,插件也被視為一套相關的 mojo。創建自定義的 Maven 2 插件超出了本教程的范圍;參見 參考資料,以獲取更多信息。

    Maven 2 是預先打包好的,以便于下載,它和許多常用插件一起使用。大多數典型開發任務不需要使用額外插件。

    在開始編寫自己的插件前,您應該先參考一下列出流行 Maven 2 插件的 Web 站點(參見 參考資料),看一下您需要的插件是不是已經有了。圖 5 顯示了 Maven Plugin Matrix(參見 參考資料),它提供了許多可用插件的兼容性信息:



    圖 5. Maven Plugin Matrix
     Maven Plugin Matrix




    回頁首


    將 mojo 綁定到生命周期各階段

    Maven 引擎在執行構建生命周期中相應的階段時,執行插件中的 mojo(構建任務)。插件的 mojo 和生命周期中的階段間的關聯叫做綁定 。插件開發人員能夠靈活地將一個或多個生命周期階段和一個插件關聯起來。





    回頁首


    默認的生命周期的各階段

    Maven 對構建生命周期的固定理解包含了許多不同的階段。表 1 簡短地描述了各個階段:



    表 1. Maven 2 默認生命周期的各階段
    生命周期階段 描述
    驗證 確保當前配置和 POM 的內容是有效的。這包含對 pom.xml 文件樹的驗證。
    初始化 在執行構建生命周期的主任務之前可以進行初始化。
    生成源碼 代碼生成器可以開始生成在以后階段中處理或編譯的源代碼。
    處理源碼 提供解析、修改和轉換源碼。常規源碼和生成的源碼都可以在這里處理。
    生成資源 可以生成非源碼資源。通常包括元數據文件和配置文件。
    處理資源 處理非源碼資源。修改、轉換和重定位資源都能在這階段發生。
    編譯 編譯源碼。編譯過的類被放到目標目錄樹中。
    處理類 處理類文件轉換和增強步驟。字節碼交織器和常用工具常在這一階段操作。
    生成測試源碼 mojo 可以生成要操作的單元測試代碼。
    處理測試源碼 在編譯前對測試源碼執行任何必要的處理。在這一階段,可以修改、轉換或復制源代碼。
    生成測試資源 允許生成與測試相關的(非源碼)資源。
    處理測試資源 可以處理、轉換和重新定位與測試相關的資源。
    測試編譯 編譯單元測試的源碼。
    測試 運行編譯過的單元測試并累計結果。
    打包 將可執行的二進制文件打包到一個分布式歸檔文件中,如 JAR 或 WAR。
    前集成測試 準備集成測試。這種情況下的集成測試是指在一個受到一定控制的模擬的真實部署環境中測試代碼。這一步能將歸檔文件部署到一個服務器上執行。
    集成測試 執行真正的集成測試。
    后集成測試 解除集成測試準備。這一步涉及測試環境重置或重新初始化。
    檢驗 檢驗可部署歸檔的有效性和完整性。過了這個階段,將安裝該歸檔。
    安裝 將該歸檔添加到本地 Maven 目錄。這一步讓其他可能依賴該歸檔的模塊可以使用它。
    部署 將該歸檔添加到遠程 Maven 目錄。這一步讓這個工件能為更多的人所用。

    Maven 從開源社區中汲取了十多年的項目構建管理經驗。很難找到一個構建周期不符合表 1 中的生命周期階段的軟件項目。

    啟動 Maven 2 引擎后,它會按順序經歷表 1 中的各階段,執行可能與該階段綁定的 mojo。每個 mojo 則可以使用 Maven 2 豐富的 POM 支持、依賴項管理,也可以訪問執行這一專門任務時的構建狀態信息。

    調用 Maven 2 引擎時,可以將一個生命周期階段指定為命令行參數。該引擎一直執行到指定的階段(包括該指定的階段)。包含的階段中所有的 mojo 都會被觸發。

    簡短地說,這就是 Maven 2 的操作原理。在下一部分里,您將直接面對操作。對 Maven 操作、它的依賴項管理模型和它的 POM 有了基本的理解,您會發現實踐 Maven 2 是一項十分簡單的練習。

    下載和安裝 Maven 2

    根據下列步驟下載和安裝 Maven 2:

    1. 從 Maven 項目的官方站點下載 Maven 2 二進制文件(參見 參考資料)。
    2. 將二進制發布文件解壓到選定的目錄。
    3. InstallationDirectory\bin 目錄添加到 PATH 環境變量。

    為檢驗安裝,鍵入 mvn -help 命令。您將看到清單 3 中的幫助頁面。



    清單 3. 使用 mvn -help 命令檢驗安裝
                C:\>mvn -help
    usage: mvn [options] [<goal(s)>] [<phase(s)>]
    Options:
    -C,--strict-checksums Fail the build if checksums don't match
    -c,--lax-checksums Warn if checksums don't match
    -P,--activate-profiles Comma-delimited list of profiles to
    activate
    -ff,--fail-fast Stop at first failure in reactorized builds
    -fae,--fail-at-end Only fail the build afterwards; allow all
    non-impacted builds to continue
    -B,--batch-mode Run in non-interactive (batch) mode
    -fn,--fail-never NEVER fail the build, regardless of project
    result
    -up,--update-plugins Synonym for cpu
    -N,--non-recursive Do not recurse into sub-projects
    -npr,--no-plugin-registry Don't use ~/.m2/plugin-registry.xml for
    plugin versions
    -U,--update-snapshots Update all snapshots regardless of
    repository policies
    -cpu,--check-plugin-updates Force upToDate check for any relevant
    registered plugins
    -npu,--no-plugin-updates Suppress upToDate check for any relevant
    registered plugins
    -D,--define Define a system property
    -X,--debug Produce execution debug output
    -e,--errors Produce execution error messages
    -f,--file Force the use of an alternate POM file.
    -h,--help Display help information
    -o,--offline Work offline
    -r,--reactor Execute goals for project found in the
    reactor
    -s,--settings Alternate path for the user settings file
    -v,--version Display version information

    實踐 Maven 2:您的第一個 Maven 2 項目

    在第一個實踐的例子里,您將看到如何用最小的努力使用 Maven 2 構建簡單項目。Maven 2 內置的關于 Java 項目的知識消除了其他構建工具也許必須要經歷的冗長的配置過程。

    處理數值操作的類

    該例使用了一個處理數值操作的類。這個主體類的源代碼(叫做 NumOps)如清單 4 所示。



    清單 4.NumOps 類
                package com.ibm.devworks;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    public class NumOps {
    private List <Operation> ops = new ArrayList
    <Operation>();
    public NumOps() {
    ops.add( new AddOps());
    }
    public Operation getOp(int i)
    { Operation retval;
    if (i > ops.size())
    { retval = null;
    } else {
    retval = (Operation) ops.get(i);
    } return retval;
    }
    public int size() {
    return ops.size();
    }
    public static void main( String[] args ) {
    NumOps nop = new NumOps();
    for (int i=0; i < nop.size(); i++) {
    System.out.println( "2 " +
    nop.getOp(i).getDesc() +
    " 1 is " +
    nop.getOp(i).op(2,1) );
    }
    }
    }

    NumOps 類管理一個能夠在兩個整數上執行數值操作的對象集。main 方法創建一個 NumOps 實例,然后調用由 NumOps 管理的每個對象,同時分別調用它的 getDesc() 方法和 op() 方法。由 NumOps 管理的所有對象都實現了在 Operation.java 中定義的 Operation 接口,接口代碼如清單 5 所示:



    清單 5. Operation 接口
                package com.ibm.devworks;
    public interface Operation {
    int op(int a, int b);
    String getDesc();
    }

    在這個初始的例子里定義的惟一操作是一個 AddOps 類,如清單 6 所示:



    清單 6. AddOps 類
                package com.ibm.devworks;
    public class AddOps implements Operation {
    public int op(int a, int b) {
    return a+b;
    }
    public String getDesc() {
    return "plus";
    }
    }

    執行 NumOps 類時,會打印出下列輸出:

     2 plus 1 is 3





    回頁首


    使用 Archetype 來創建初始項目

    要創建能用 Maven 構建的簡單 Java 項目所需的一切,可以使用 Archetype 插件,它是 Maven 2 中的標準插件。不同于構建階段插件,Archetype 在 Maven 項目構建生命周期之外運行,用于創建 Maven 項目。在您想要包含 NumOps 項目的目錄中執行下列命令(將所有命令敲在一行):

    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes
    -DgroupId=com.ibm.devworks -DartifactId=NumOps

    該命令為 Archetype 插件提供您模塊的坐標:com.ibm.devworks/NumOps/1.0-SNAPSHOT。在此情況下,不需要指定版本,因為 Archetype 插件常默認為 1.0-SNAPSHOT。此命令為項目創建了一個起始的 pom.xml 文件,也創建了規范的 Maven 2 目錄結構。您將在本教程源代碼下載處的 example1 目錄下找到該代碼(參見 下載)。

    該輸出應該與清單 7 類似:



    清單 7. 使用 Maven Archetype 創建 NumOps 項目
                [INFO] Scanning for projects...
    [INFO] Searching repository for plugin with prefix: 'archetype'.
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] Building Maven Default Project
    [INFO] task-segment: [archetype:create] (aggregator-style)
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus
    ...
    [INFO] [archetype:create]
    [INFO] Defaulting package to group ID: com.ibm.devworks
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] Using following parameters for creating Archetype: maven-archetype-quicks
    tart:RELEASE
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] Parameter: groupId, Value: com.ibm.devworks
    [INFO] Parameter: packageName, Value: com.ibm.devworks
    [INFO] Parameter: basedir, Value: C:\temp\maven
    [INFO] Parameter: package, Value: com.ibm.devworks
    [INFO] Parameter: version, Value: 1.0-SNAPSHOT
    [INFO] Parameter: artifactId, Value: NumOps
    [INFO] ********************* End of debug info from resources from generated POM
    ***********************
    [INFO] Archetype created in dir: C:\temp\maven\NumOps
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1 second
    [INFO] Finished at: Sat Dec 02 22:04:02 EST 2006
    [INFO] Final Memory: 4M/8M
    [INFO] ------------------------------------------------------------------------

    Archetype 插件創建了一個目錄樹、一個 pom.xml 文件和一個占位符 App.java 應用程序文件。它也為單元測試源碼創建了一棵目錄樹,還創建了一個占位符 AppTest.java 單元測試文件。這個項目已經準備就緒。圖 6 顯示了該 Archetype 插件創建的目錄和文件。



    圖 6. Archetype 生成的目錄和文件
    Archetype 生成的目錄和文件

    您只需將 NumOps.java、Operation.java 和 AddOps.java 文件移到 App.java 的位置,并移除 App.java。在下一部分中,將做出一些改變來定制生成的 pom.xm。

    定制 POM

    Maven 2 通過該 pom.xml 文件了解您的項目。該文件由 Archetype 按照 NumOps 生成,如清單 8 所示:



    清單 8. Archetype 生成的 POM - pom.xml
                <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibm.devworks</groupId>
    <artifactId>NumOps</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>Maven Quick Start Archetype</name>
    <url>http://maven.apache.org</url>
    <dependencies>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
    </dependency>
    </dependencies>
    </project>

    請注意:在測試階段中(通過 <scope> 標記),Archetype 如何定義模塊的坐標、如何將類型定義為 JAR 歸檔以及如何將 JUnit 指定為一個依賴項。要為您的新項目定制這個 pom.xml 文件,請參照清單 9 中突出顯示的部分,稍作改動。



    清單 9. 為 NumOps 項目定制生成的 pom.xml 文件
                        <project xmlns=http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibm.devworks</groupId>
    <artifactId>NumOps</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>Intro to Maven 2 Example 1</name> <url>http://www.ibm.com/java</url> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>

    額外的 <build> 標記是必要的,用來覆蓋源代碼,以達到 Java 代碼的水平。默認情況下,采用的是 JDK 1.4,但您的代碼使用了泛型,因而需要 JDK 5.0 編譯。

    編譯定制的項目

    現在可以使用 mvn compile 命令編譯 NumOps 項目。 這個命令使 Maven 2 引擎從構建生命周期一直運行到編譯階段,并執行相應的 mojo。您應該看到構建成功的報告,報告中在目標目錄樹里創建了三個類文件(如清單 10 所示)。如果這是第一次運行,那會花點時間,因為一些依賴項需要經過 Internet 從中央存儲庫下載。



    清單 10. NumOps 項目中 mvn 編譯的輸出
                [INFO] Scanning for projects...
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] Building Intro to Maven 2 Example 1
    [INFO] task-segment: [compile]
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] [resources:resources]
    [INFO] Using default encoding to copy filtered resources.
    [INFO] [compiler:compile]
    Compiling 3 source files to C:\temp\maven\NumOps\target\classes
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1 second
    [INFO] Finished at: Sat Dec 02 22:52:16 EST 2006
    [INFO] Final Memory: 3M/7M
    [INFO] ------------------------------------------------------------------------





    回頁首


    添加單元測試

    項目開發的最佳實踐通常要求對所有代碼模塊進行單元測試。Maven 2 為您創建了一個占位符 AppTest.java 單元測試文件。現在,將文件名改為 NumOpsTest.java,請參照清單 11 中突出顯示的部分,對生成的單元測試做出改動。也可以從源代碼下載處復制單元測試的源代碼(參見 下載)。



    清單 11. 為項目添加 NumOpsTest 單元測試
                package com.ibm.devworks;
    import junit.framework.Test;
    import junit.framework.TestCase;
    import junit.framework.TestSuite;
    /**
    * Unit test for simple App.
    */
    public class NumOpsTest
    extends TestCase
    { /** * Create the test case * * @param testName name of the test case */ public NumOpsTest( String testName )
    {
    super( testName );
    }
    ...
    public void testNumOps() { NumOps nops = new NumOps(); assertTrue( nops.size() == 1); assertTrue( nops.getOp(0).getDesc().equals("plus")); assertTrue( nops.getOp(0).op(2,1) == 3); } }

    現在可以使用 mvn test 命令運行所有的 mojo 一直到測試階段。

    Maven 2 編譯源碼和單元測試。然后運行測試,同時報告成功、失敗和錯誤的數目,如清單 12 所示:



    清單 12. 執行 mvn 測試來編譯項目和運行單元測試
                [INFO] Scanning for projects...
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] Building Intro to Maven 2 Example 1
    [INFO] task-segment: [test]
    [INFO] -------------------------------------------------------------------------
    ---
    [INFO] [resources:resources]
    [INFO] Using default encoding to copy filtered resources.
    [INFO] [compiler:compile]
    [INFO] Nothing to compile - all classes are up to date
    [INFO] [resources:testResources]
    [INFO] Using default encoding to copy filtered resources.
    [INFO] [compiler:testCompile]
    Compiling 1 source file to C:\temp\maven\NumOps\target\test-classes
    [INFO] [surefire:test]
    [INFO] Surefire report directory: C:\temp\maven\NumOps\target\surefire-reports
    -------------------------------------------------------
    T E S T S
    -------------------------------------------------------
    Running com.ibm.devworks.NumOpsTest
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.031 sec
    Results :
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 2 seconds
    [INFO] Finished at: Sat Dec 02 23:04:27 EST 2006
    [INFO] Final Memory: 3M/6M
    [INFO] ------------------------------------------------------------------------

    實踐 Maven 2:參與多個項目構建

    使用 Maven 2 構建和測試簡單項目是很直接的。本部分用第二個例子來展示更現實也更為通用的多模塊項目。

    擴展 NumOps 樣例

    NumOps 的例子將在此處的第二個例子里得到擴展。添加一個新 SubOps 類來支持減法,添加一個新 MulOps 類來支持乘法。

    Operation 接口和 AddOps 類現在己從 NumOps 項目中移走。相反,它們和新的 SubOpsMulOps 類一起放到了一個叫做 OpsImp 的新項目中。圖 7 顯示了 NumOpsOpsImp 項目間的這種關系:



    圖 7. NumOps 和 OpsImp 間的關系
    NumOps 和 OpsImp 間的關系

    在大型軟件開發項目中,子項目和子模塊之間常存在依賴性。您可以將這里的這項技術應用到有著多個相互依賴項的任何多模塊 Maven 項目中。

    清單 13 里的 SubOps 在編碼上和 AddOps 類似。這里沒有顯示的 MulOps 也類似;您可以看一下隨附的代碼來了解詳情(參見 下載)。



    清單 13. 實現 Operation 接口的新 SubOps 類
                package com.ibm.devworks;
    public class SubOps implements Operation {
    public int op(int a, int b) {
    return a-b;
    }
    public String getDesc() {
    return "minus";
    }
    }

    現在修改了 NumOps 的構造函數來創建一個 SubOps 實例和一個 MulOps 實例。參見隨附的源代碼獲取詳情。





    回頁首


    創建主項目

    為和這兩個項目一起運行,主項目創建在比 NumOpsOpsImp 的項目目錄高一級的目錄。NumOpsOpsImp 項目都使用標準 Maven 項目目錄布局。在最頂部,項目目錄只包含一個 pom.xml 文件。圖 8 顯示了新的子目錄結構,緊跟在主目錄之下:



    圖 8. 多模塊項目的目錄結構
    多模塊項目的目錄結構

    可以在分發代碼的 example2 子目錄中找到這個多模塊項目的代碼(參見 下載)。清單 14 顯示了頂層的 pom.xml 文件:



    清單 14. 多模塊項目頂層的 pom.xml 文件
                <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibm.devworks</groupId> <artifactId>mavenex2</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <name>Maven Example 2</name> <url>http://maven.apache.org</url> <modules>
    <module>NumOps</module>
    <module>OpsImp</module>
    </modules>
    <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>com.ibm.devworks</groupId> <artifactId>OpsImp</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>

    新代碼以粗體突出顯示。首先,這個主項目的工件 ID 是 mavenex2,其打包類型是 pom。這向 Maven 2 傳遞出這樣的信號:這是一個多模塊項目。

    隨后,<modules> 標記指定組成此項目的兩個模塊:NumOpsOpsImp

    這個主項目的子模塊能從這個 pom.xml 文件中繼承屬性。說得更具體一點,這些子模塊都不需要將 JUnit 聲明為一個依賴項,即使它們都包含單元測試。這是因為它們繼承了頂層定義的 JUnit 依賴項。

    <dependencyManagement> 標記不指定此模塊依賴的依賴項。相反,它主要由子模塊使用。子模塊能指定 <dependencyManagement> 標記中任何條目的依賴項,而無需指定具體的版本號。當項目樹更改依賴項的版本號時,這很有用,可以使需編輯的條目數目最小化。在本例中,OpsImp 項目的版本號是使用 ${project.version} 指定的。在執行 Maven 時,這是一個會被相應值所填充的參數。





    回頁首


    從主 POM 中繼承

    前進到下一層的 OpsImp 目錄,可以找到該模塊的 pom.xml 文件,如清單 15 所示:



    清單 15. 新 OpsImp 項目的 pom.xml 文件
                <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <parent>
    <groupId>com.ibm.devworks</groupId>
    <artifactId>mavenex2</artifactId>
    <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion> <artifactId>OpsImp</artifactId> <packaging>jar</packaging> </project>

    <parent> 元素指定此模塊所繼承自的主 POM。從父模塊中繼承極大地簡化了這個 pom.xml。只需要覆蓋該工件 ID 并打包。此模塊繼承了其父模塊的依賴項:JUnit 模塊。

    NumOps pom.xml 也從其父模塊中繼承,也相當簡單。這個 pom.xml 顯示在清單 16 中:



    清單 16. NumOps 項目中顯示 POM 繼承關系的 pom.xml
                <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <parent>
    <groupId>com.ibm.devworks</groupId>
    <artifactId>mavenex2</artifactId>
    <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>NumOps</artifactId>
    <packaging>jar</packaging>
    <dependencies> <dependency> <groupId>com.ibm.devworks</groupId> <artifactId>OpsImp</artifactId> </dependency> </dependencies> </project>

    發現有效的 POM
    只要從一個高層 POM 中繼承,您總能在了解了所有繼承元素后發現相對應的 pom.xml 是什么樣。顯示 “effective POM” 的命令是 mvn help:effective-pom。您將看到一些您還沒有指定的元素。這些都是從 Super POM 中繼承的。每個項目 pom.xml 都從 Maven 內嵌的 Super POM 中隱式地繼承。

    NumOps POM 中有意思的一處是將 OpsImp 項目指定為一個依賴項。請注意,在這個依賴項中沒有指定任何版本號。在它的父項目的 <dependencyManagement> 元素里已經指定了首選的版本號。

    在項目頂層,現在可以用 mvn compile 命令編譯全部兩個模塊,或用 mvn test 命令為兩個模塊運行單元測試。也可以運行 mvn install 將打包的模塊安裝到本地目錄中。這使得任何依賴于它的模塊可以不訪問源代碼就能解析依賴項。





    回頁首

    在 Eclipse 3.2 中安裝 Maven 2.x Plug-in

    如果您在日常開發中使用 Eclipse IDE,那么您應該在 Eclipse 中下載和安裝 Maven 2.x Plug-in。這個插件有助于在 Eclipse IDE 中操作 Maven 項目。參見 參考資料 獲取有關此插件的項目信息。

    可以使用 Eclipse 的軟件更新向導在 Eclipse 下安裝 Maven 2.X Plug-in:

    1. 從 Eclipse 的 Help 菜單中選擇 Software Updates>Find and Install...

    2. 選擇 Search for new features to install,單擊 Next。您將看到更新站點向導,如圖 9 所示:

      圖 9. Eclipse 更新站點向導
      Eclipse 更新站點向導
    3. 單擊 New Remote Site 按鈕。

    4. 在彈出的對話框中,輸入 Maven 2.x Plug-in for Eclipse 更新站點,如圖 10 所示:

      圖 10. Eclipse 新的遠程站點
      Eclipse 新的遠程站點
    5. 選擇要安裝的插件,讓安裝向導重啟工作空間。重啟后,您就可以在 Eclipse 中使用 Maven Plug-in 的功能了。

    在 Eclipse 3.2 中使用 Maven 2 Plug-in

    本節涵蓋了 Eclipse 中 Maven 2.x Plug-in 的一些常用功能。

    在您的項目可以使用 Maven 2 插件功能前,需要在一個 Eclipse 項目中啟用 Maven 屬性。右鍵單擊您想要向其中添加 Maven 支持的項目,選擇 Maven2>Enable

    為確保項目的目錄結構符合 Maven 的預期,您應先創建 Maven 目錄結構(或者手動或者使用 Archetype),然后將該項目添加到 Eclipse 中。

    在存儲庫中實時搜索依賴項

    使用插件將依賴項添加到 pom.xml 很簡單。右鍵單擊該項目的 pom.xml,然后選擇 Maven2>Add Dependency。這會啟動 Repository Search 向導。鍵入您要尋找的依賴項名稱開頭的一些字母,該向導會在中央存儲庫中搜索任何相匹配的工件。相匹配的工件的所有詳情都會呈現給您,以幫助您選擇依賴項。圖 11 顯示了搜索 JUnit 工件的結果:



    圖 11. Maven Repository Search 向導
    Maven Repository Search 向導

    一旦選定了想要的工件的版本,單擊 OK,插件就會自動地將一個新的 <dependency> 元素添加到 pom.xml 中。





    回頁首


    調用 Maven 構建

    一個構建涉及到能從 Eclipse 中啟動的生命周期的任何階段。首先,確保啟用了 Maven 的項目當前是打開的。然后,從 Eclipse 菜單中選擇 Run>External Tools>External Tools...。這將顯示 External Tools 向導,如圖 12 所示:



    圖 12.使用 Eclipse External Tool 向導通過 Maven 構建
    使用 Eclipse External Tool 向導通過 Maven 構建

    給這個配置文件起名,然后通過單擊 Goals... 按鈕選擇一個生命周期階段。單擊 Run 運行 Maven。

    Maven 輸出顯示在 Eclipse 的 Console 選項卡中。

    結束語

    在本教程中,您:

    • 探究了 Maven 2 設計背后的模型和動機
    • 理解了所有重要的 Maven POM
    • 觀察了 Maven 存儲庫和坐標系統是如何簡化復雜依賴項管理的
    • 在快捷簡單的項目中使用了 Maven 2
    • 了解了 Maven 2 如何有助于大型多模塊項目
    • 實際體驗了 Maven 2 Eclipse Plug-in
    • 直接觀察了 Maven 2 如何便利您的日常項目構建和源碼/二進制管理活動

    隨著軟件開發協作的發展,Maven 也會不斷發展和改變來適應這種需求。作為大多數大型開源項目的骨干構建工具,它一定能從開發者社區不斷提供的改進意見中獲益。

    一旦理解了 Maven 2 的動機和它想要戰勝的挑戰,了解 Maven 2 就不困難了。作為構建工具,Maven 2 高效可用,即使是一個十足的新手在一個與世隔絕的地方開發項目,他也會深感 Maven 2 的這一特性。開始在您自己的開發項目中使用 Maven 2 并參加一個開源開發社區吧,很快,您也將能夠對 Maven 2 的發展方向和進程有所影響。

    下載

    描述 名字 大小 下載方法
    本教程的樣例代碼 j-mavenv2.zip 34.1KB HTTP

    參考資料

    學習
    • Maven 項目的 Web 站點:獲取有關 Maven 2 的最新詳情,包括設置參考和如何創建自定義插件的細節。

    • Maven Plugin Matrix:查閱這份參考資料,獲取有關插件兼容性的信息。

    • Better Builds with Maven :由 Maven 2 開源項目的創建者和主要參與者編寫的一本關于 Maven 2 的出色而全面的書。

    • Java 技術專區:數百篇關于 Java 編程各方面的文章。

    • 瀏覽 技術書店 中關于這些技術主題和其他技術主題的書籍。


    獲得產品和技術

    關于作者

    Sing Li 的照片

    Sing Li 是一位顧問和多產的作家,具有二十多年的行業工作經驗。他編寫了 Professional Apache GeronimoBeginning JavaServer PagesProfessional Apache Tomcat 5Pro JSP - Third Edition、Early Adopter JXTA、Professional Jini、Beginning J2ME: From Novice to Professional, Third EditionProfessional Apache Geronimo 和許多其他書籍。Sing 也為技術雜志供稿,還參加開源社區。他是開源、VOIP 和 P2P 運動的積極倡導者。可以通過 westmakaha@yahoo.com 和 Sing 聯系。

    posted on 2008-01-10 19:59 禮物 閱讀(3211) 評論(1)  編輯  收藏 所屬分類: maven2

    評論

    # re: Apache Maven 2 簡介(最全的文檔) 2010-08-18 17:38 逸飛
    郁悶,圖片看不到!一直提示登陸框!  回復  更多評論
      

    主站蜘蛛池模板: 足恋玩丝袜脚视频免费网站| 国产大陆亚洲精品国产| 99视频免费在线观看| 国产偷国产偷亚洲高清日韩| 另类图片亚洲校园小说区| 免费A级毛片无码A| 4hu四虎免费影院www| 亚洲精品无码午夜福利中文字幕| 99在线热播精品免费99热| 亚洲av无码成人黄网站在线观看| 久久免费精彩视频| 亚洲精品韩国美女在线| 一二三四在线播放免费观看中文版视频 | 亚洲精品乱码久久久久久下载| 久久久免费的精品| 亚洲综合视频在线观看| 成人AV免费网址在线观看| 亚洲第一综合天堂另类专| 无码不卡亚洲成?人片| 国产福利免费视频| 国产亚洲高清不卡在线观看| 久久久久免费看成人影片| 精品在线免费视频| 亚洲精品无码久久久| a级片免费观看视频| 亚洲视频在线免费播放| 搡女人免费视频大全| 福利片免费一区二区三区| 黑人大战亚洲人精品一区| 久久久久久国产精品免费无码| 亚洲乱码一区av春药高潮| 免费看国产一级片| 久久久久久影院久久久久免费精品国产小说 | 99视频免费播放| 亚洲AV无码专区在线电影成人| 国产亚洲情侣一区二区无码AV | 亚洲福利电影一区二区?| 免费激情视频网站| 精品国产麻豆免费人成网站| 日韩亚洲国产二区| 久久成人免费播放网站|