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

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

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

    鷹翔宇空

    學(xué)習(xí)和生活

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
    引自:http://www-128.ibm.com/developerworks/cn/java/j-maven/

    項(xiàng)目管理: Maven 讓事情變得簡單

    給您的下一個(gè) Java 構(gòu)建添加項(xiàng)目管理特性

    developerWorks
    文檔選項(xiàng)
    將此頁作為電子郵件發(fā)送

    將此頁作為電子郵件發(fā)送

    未顯示需要 JavaScript 的文檔選項(xiàng)


    對此頁的評價(jià)

    幫助我們改進(jìn)這些內(nèi)容


    級別: 初級

    Charles Chan, 高級軟件開發(fā)人員, Finetix LLC

    2003 年 7 月 30 日

    盡管 Ant 對于構(gòu)建 Java 程序而言是事實(shí)上的標(biāo)準(zhǔn)工具,但這個(gè)工具在許多方面都不勝任項(xiàng)目管理任務(wù)。相反,Ant 提供的東西,Maven(出自 Apache Jakarta 項(xiàng)目的高級項(xiàng)目管理工具)都能提供,而且更多。Java 開發(fā)人員 Charles Chan 將介紹 Maven 的特性,并循序漸進(jìn)地指導(dǎo)您進(jìn)行一次完整的 Maven 項(xiàng)目設(shè)置。

    目前,絕大多數(shù)開發(fā)人員都把 Ant 當(dāng)作 Java 編程項(xiàng)目的標(biāo)準(zhǔn)構(gòu)建工具。遺憾的是,Ant 的項(xiàng)目管理工具(作為 make 的替代工具)不能滿足絕大多數(shù)開發(fā)人員的需要。通過檢查 Ant 構(gòu)建文件,很難發(fā)現(xiàn)項(xiàng)目的相關(guān)性信息和其它元信息(如開發(fā)人員/擁有者、版本或站點(diǎn)主頁)。

    Maven 除了以程序構(gòu)建能力為特色之外,還提供 Ant 所缺少的高級項(xiàng)目管理工具。由于 Maven 的缺省構(gòu)建規(guī)則有較高的可重用性,所以常常用兩三行 Maven 構(gòu)建腳本就可以構(gòu)建簡單的項(xiàng)目,而使用 Ant 則需要十幾行。事實(shí)上,由于 Maven 的面向項(xiàng)目的方法,許多 Apache Jakarta 項(xiàng)目現(xiàn)在使用 Maven,而且公司項(xiàng)目采用 Maven 的比例在持續(xù)增長。

    Maven vs Ant

    那么,Maven 和 Ant 有什么不同呢?在回答這個(gè)問題以前,我要強(qiáng)調(diào)一點(diǎn):Maven 和 Ant 針對構(gòu)建問題的兩個(gè)不同方面。Ant 為 Java 技術(shù)開發(fā)項(xiàng)目提供跨平臺構(gòu)建任務(wù)。Maven 本身描述項(xiàng)目的高級方面,它從 Ant 借用了絕大多數(shù)構(gòu)建任務(wù)。因此,由于 Maven 和 Ant 代表兩個(gè)差異很大的工具,所以我將只說明這兩個(gè)工具的等同組件之間的區(qū)別,如表 1 所示。

    表 1. Maven vs Ant

    MavenAnt
    標(biāo)準(zhǔn)構(gòu)建文件project.xml 和 maven.xmlbuild.xml
    特性處理順序
    1. ${maven.home}/bin/driver.properties
    2. ${project.home}/project.properties
    3. ${project.home}/build.properties
    4. ${user.home}/build.properties
    5. 通過 -D 命令行選項(xiàng)定義的系統(tǒng)特性
    最后一個(gè)定義起決定作用。
    1. 通過 -D 命令行選項(xiàng)定義的系統(tǒng)特性
    2. <property> 任務(wù)裝入的特性
    第一個(gè)定義最先被處理。
    構(gòu)建規(guī)則構(gòu)建規(guī)則更為動態(tài)(類似于編程語言);它們是基于 Jelly 的可執(zhí)行 XML。構(gòu)建規(guī)則或多或少是靜態(tài)的,除非使用 <script> 任務(wù)。(請參閱 參考資料以獲得相關(guān)教程。)
    擴(kuò)展語言插件是用 Jelly(XML)編寫的。插件是用 Java 語言編寫的。
    構(gòu)建規(guī)則可擴(kuò)展性通過定義 <preGoal><postGoal> 使構(gòu)建 goal 可擴(kuò)展。 構(gòu)建規(guī)則不易擴(kuò)展;可通過使用 <script> 任務(wù)模擬 <preGoal><postGoal> 所起的作用。


    回頁首


    Maven 的主要組件

    既然您了解了 Maven 和 Ant 之間的區(qū)別,讓我們來研究 Maven 的主要組件,如圖 1 所示。


    圖 1. Maven 的主要組件
    Maven 的主要組件

    項(xiàng)目對象模型

    項(xiàng)目對象模型(Project Object Model,POM)描述項(xiàng)目的各個(gè)方面。盡管對于 POM 的物理表示沒有內(nèi)在的限制,但 Maven 開發(fā)人員通常使用一個(gè) XML 項(xiàng)目文件(project.xml)。該 XML 文件格式由位于 Maven 安裝目錄中的 XML 模式(maven-project.xsd)定義。

    通常,project.xml 文件由三個(gè)主要部分組成:

    • 項(xiàng)目管理部分包括項(xiàng)目的組織、開發(fā)人員名單、源代碼位置和錯(cuò)誤跟蹤系統(tǒng) URL 等信息。
    • 項(xiàng)目相關(guān)性部分包括關(guān)于項(xiàng)目相關(guān)性的信息。當(dāng)前 Maven 實(shí)現(xiàn)(1.0 beta 測試版 8)僅支持 JAR 文件相關(guān)性。
    • 項(xiàng)目構(gòu)建和報(bào)告部分包含項(xiàng)目構(gòu)建信息(如源代碼目錄、單元測試用例目錄)和要在構(gòu)建中生成的報(bào)告。

    清單 1 顯示了帶注釋的樣本 project.xml 文件。因?yàn)?project.xml 文件中的許多元素都是可選的,所以,隨著您對 Maven 理解的加深,可以逐步使用不同的 Maven 特性。 注:在以下代碼中,可選的元素都以“可選的(OPTIONAL)”標(biāo)明。

    主文檔包含項(xiàng)目的唯一標(biāo)識和組標(biāo)識。事實(shí)證明,當(dāng)項(xiàng)目包括多個(gè)子項(xiàng)目時(shí),組標(biāo)識非常有用。所有的子項(xiàng)目應(yīng)共享同一組標(biāo)識,但每個(gè)子項(xiàng)目應(yīng)有不同的 <id>


    清單 1. 主 project.xml 框架
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <!-- A project file's root element -->
    <project>
      <!-- The POM version. This tag is currently unused. -->
      <pomVersion>3</pomVersion>
    
      <!-- A project group id. If present, the id serves as the project's
            directory name in the repository -->
      <groupId>crayola-group</groupId>
    
      <!-- A unique project identifier. The project identifier and its
            version number often generate file/directory names during the
            build. For example, a project JAR file follows the
            <id>-<version> naming convention. -->
      <id>crayola</id>
    
      <!-- A short name for the project -->
      <name>Crayola Professional</name>
    
      <!-- The project version number. Maven does not enforce a particular
            version numbering scheme. -->
      <currentVersion>0.0.1</currentVersion>
    
      ...
      <!-- 
    ---------------------------------------------------------------- -->
      <!-- Project management section                                -->
      <!-- 
    ---------------------------------------------------------------- -->
      ...
      <!-- 
    ---------------------------------------------------------------- -->
      <!-- Project dependency section                                -->
      <!-- 
    ---------------------------------------------------------------- -->
      ...
      <!-- 
    ---------------------------------------------------------------- -->
      <!-- Project build and reports section                         -->
      <!-- 
    ---------------------------------------------------------------- -->
      ...
    </project>
    

    項(xiàng)目管理部分(如清單 2 所示)主要包括可選項(xiàng)。在此部分中指定開發(fā)人員名單(帶有正確的標(biāo)識),當(dāng)您希望獲得更改日志(Change Log)報(bào)告和開發(fā)活動(Development Activity)報(bào)告時(shí)尤其要這么做。


    清單 2. 項(xiàng)目管理部分
      
    ...
    <!-- 
    ---------------------------------------------------------------- -->
      <!-- Project management section                                -->
      <!-- 
    ---------------------------------------------------------------- -->
    
      <!-- Details of the organization holding the project. Only the name
            is required. -->
      <organization>
        <name>Markers Inc.</name>
        <url>http://w3.markers.com/</url>
        
    <logo>http://w3.markers.com/logo/company-logo.gif</logo>
      </organization>
    
      <!-- (OPTIONAL) Year of inception -->
      <inceptionYear>2003</inceptionYear>
    
      <!-- (OPTIONAL) Project main package -->
      <package>com.markers.crayola.*</package>
    
      <!-- (OPTIONAL) Project logo picture (URL) -->
      <logo>http://w3.markers.com/logo/crayola.gif</logo>
    
      <!-- (OPTIONAL) GUMP repository ID. Useful only if you use GUMP. -->
      <gumpRepositoryId>crayola</gumpRepositoryId>
    
      <!-- (OPTIONAL) Project description -->
      <description>...</description>
    
      <!-- (OPTIONAL) Short project description -->
      <shortDescription>...</shortDescription>
    
      <!-- (OPTIONAL) Project site URL -->
      <url>http://w3.markers.com/crayola</url>
    
      <!-- (OPTIONAL) Issue-tracking system URL -->
      
    <issueTrackingUrl>http://w3.markers.com/jira/crayola</issueTrackingUrl>
    
      <!-- (OPTIONAL) Project site address. -->
      <siteAddress>w3.markers.com</siteAddress>
    
      <!-- (OPTIONAL) Project-site deploy directory (physical location) -->
      <siteDirectory>/www/crayola/site/</siteDirectory>
    
      <!-- (OPTIONAL) Project distribution directory (physical location) -->
      
    <distributionDirectory>/www/crayola/builds/</distributionDirectory>
    
      <!-- (OPTIONAL) Project source-repository information -->
      <repository>
        
    <connection>
    scm:cvs:pserver:anoncvs@cvs.markers.com:/home/cvspublic:crayola
    </connection>
        <url>http://cvs.markers.com/viewcvs/crayola/</url>
      </repository>
    
      <!-- (OPTIONAL) Mailing list information -->
      <mailingLists>
        <mailingList>
          <name>Dev List</name>
          
    <subscribe>dev-subscribe@crayola.markers.com</subscribe>
          
    <unsubscribe>dev-unsubscribe@crayola.markers.com</unsubscribe>
        </mailingList>
        ...
      </mailingLists>
    
      <!-- Developers involved in this project -->
      <developers>
        <developer>
          <name>John Smith</name>
          <id>jsmith</id>
          <email>jsmith@markers.com</email>
        </developer>
        ...
      </developers>
    

    將清單 3 中的信息與一個(gè)中央構(gòu)件資源庫一起使用,將消除幾個(gè)常見的構(gòu)建問題(包括錯(cuò)誤配置的 CLASSPATH 或相關(guān)性-版本不匹配)。


    清單 3. 項(xiàng)目相關(guān)性部分
      <!-- 
    ---------------------------------------------------------------- -->
      <!-- Project dependency section                                -->
      <!-- 
    ---------------------------------------------------------------- -->
    
      <dependencies>
    
        <!-- This project depends on the JAR file "commons-beanutils-1.5.jar"
              in the Maven repository's commons-beanutils/jars subdirectory
              (more about repository later). -->
        <dependency>
          <groupId>commons-beanutils</groupId>
          <artifactId>commons-beanutils</artifactId>
          <version>1.5</version>
        </dependency>
    
        <!-- This project depends on the JAR file "commons-lib-2.1.jar" in
              the Maven repository's markers/jars subdirectory. -->
        <dependency>
          <groupId>markers</groupId>
          <artifactId>commons-lib</artifactId>
          <version>2.1</version>
        </dependency>
    
      </dependencies>
    

    項(xiàng)目構(gòu)建和報(bào)告部分(如清單 4 所示)包含用于配置某些 Maven 插件的重要構(gòu)建和報(bào)告信息。例如,可以配置 Maven 在站點(diǎn)文檔生成時(shí)包含還是排除某些報(bào)告。


    清單 4. 項(xiàng)目構(gòu)建部分
      ...
      <!-- 
    ---------------------------------------------------------------- -->
      <!-- Project build and reports section                         -->
      <!-- 
    ---------------------------------------------------------------- -->
    
      <build>
    
        <!-- (OPTIONAL) Build notification email address. -->
        <nagEmailAddress>jsmith@markers.com</nagEmailAddress>
    
        <!-- (OPTIONAL) Defines where the Java source resides. -->
        <sourceDirectory>src/java</sourceDirectory>
    
        <!-- (OPTIONAL) Defines where the Java source for unit test-cases
              resides. -->
        
    <unitTestSourceDirectory>test/java</unitTestSourceDirectory>
    
        <!-- (OPTIONAL) Unit test-case file pattern. -->
        <unitTest>
          <includes>
            <include>**/*Test.java</include>
          </includes>
        </unitTest>
    
        <!-- (OPTIONAL) Resources packaged inside the JAR file. -->
        <resources/>
    
        <!-- (OPTIONAL) The reports tag lets you select which reports you
              want generated for your site. In this case, only the checkstyle
              report will generate. -->
      </build>
    
      <reports>
        <report>
          maven-checkstyle-plugin
        </report>
      </reports>
    

    項(xiàng)目依靠庫來實(shí)現(xiàn)其功能。例如,您的項(xiàng)目可能依靠 log4j 進(jìn)行日志記錄,依靠 Xalan 進(jìn)行 XSLT 轉(zhuǎn)換。對于 J2EE 項(xiàng)目,Web 組件可能依靠 EJB 組件來執(zhí)行業(yè)務(wù)操作。Maven 可以讓您用它的 POM 來表示不同的相關(guān)性。您可以用表 2 所示的標(biāo)記在 project.xml 文件中描述每一個(gè)相關(guān)性。

    表 2. 項(xiàng)目相關(guān)性部分

    groupId告訴 Maven 資源庫內(nèi)哪個(gè)子目錄中包含相關(guān)性文件。
    artifactId告訴 Maven 該構(gòu)件的唯一標(biāo)識。
    version表示相關(guān)性的版本號。
    jar(可選的)表示相關(guān)性的 JAR 文件。在絕大多數(shù)情況下,可以從相關(guān)性的 <artifactId><version> 構(gòu)造 JAR 文件的名稱。
    type(可選的)相關(guān)性的類型;如 jar 和分發(fā)版等。缺省值是 jar。
    url(可選的)相關(guān)性項(xiàng)目的 URL,在相關(guān)性是在因特網(wǎng)上找到的第三方庫時(shí)非常有用。

    資源庫

    資源庫是另一個(gè)主要的 Maven 組件。在有多個(gè)項(xiàng)目的基于 Java 的站點(diǎn)中,由第三方庫組成的中央資源庫常常確保項(xiàng)目之間的一致性。Maven 使資源庫的結(jié)構(gòu)符合標(biāo)準(zhǔn),并且支持駐留在因特網(wǎng)或內(nèi)部網(wǎng)上的遠(yuǎn)程資源庫。清單 5 顯示了資源庫的常規(guī)結(jié)構(gòu)。


    清單 5. 資源庫
    repository
    |-- ant                   <-- project group ID -->
    |   `-- jars              <-- artifact type, followed by 's', 
    |                         <-- e.g. jars, wars, ears -->
    |       `-- ant-1.5.1.jar <-- actual artifact -->
    ...
    

    要?jiǎng)?chuàng)建遠(yuǎn)程資源庫,只需將這個(gè)資源庫的目錄部署在網(wǎng)站中。Maven 建議使用遠(yuǎn)程資源庫以便于集中維護(hù),您將會最大程度地實(shí)現(xiàn)項(xiàng)目之間資源的共享。為避免每次構(gòu)建時(shí)都要下載文件,Maven 在首次下載必需的相關(guān)性資源時(shí)就自動地將其高速緩存在本地資源庫中。Maven 將表 3 中所示的特性用于遠(yuǎn)程資源庫和本地資源庫。

    表 3. 用于遠(yuǎn)程資源庫和本地資源庫的特性

    maven.repo.remote用以逗號分隔的 URL 列表指定遠(yuǎn)程資源庫;缺省情況下使用 http://www.ibiblio.org/maven。
    maven.proxy.hostmaven.proxy.portmaven.proxy.usernamemaven.proxy.password如果位于防火墻后面并且需要代理認(rèn)證才能訪問因特網(wǎng),這些設(shè)置將派上用場。
    maven.repo.local指定已下載的相關(guān)資源的高速緩存位置,缺省值為 ${MAVEN_HOME}/repository 。在 UNIX 環(huán)境中,為了與多個(gè)團(tuán)隊(duì)共享資源庫目錄,可以為開發(fā)人員創(chuàng)建一個(gè)特殊的組,然后給予這個(gè)組對資源庫目錄的讀/寫訪問權(quán)。
    Maven 中的 Ant 任務(wù)

    Maven 中的 goal 可在其定義中包含任何有效的 Ant 任務(wù),這一點(diǎn)有助于您快速掌握 Maven 以及保護(hù)您的 Ant 投入。

    goal

    Maven 中的 goal 類似 Ant 中的 target 。兩者都包含實(shí)現(xiàn) goal(或 target)時(shí)會執(zhí)行的任務(wù)。要在命令行中實(shí)現(xiàn)特定的 goal,可輸入 maven <goal>

    要列出所有已定義的 goal,可使用 maven -g 。表 4 列出了常用的 goal。

    表 4. 常用的 goal

    java:compile編譯所有 Java 源代碼。
    jar創(chuàng)建已編譯的源代碼的 JAR 文件。
    jar:install將已創(chuàng)建的 JAR 文件發(fā)布到本地資源庫,使得其它項(xiàng)目可訪問該 JAR 文件。
    site創(chuàng)建項(xiàng)目站點(diǎn)文檔。缺省站點(diǎn)文檔包含關(guān)于項(xiàng)目的有用信息,如包/類相關(guān)性、編碼風(fēng)格一致性、源代碼交叉引用、單元測試結(jié)果或 Javadoc。要生成的報(bào)告列表是可定制的。
    site:deploy部署生成的站點(diǎn)文檔。

    Maven 的 goal 是可擴(kuò)展和可重用的。知道了這一點(diǎn)后,在編寫自己的 goal 之前,可先在 Maven 站點(diǎn)上或 ${MAVEN_HOME}/plugins 中查看 Maven 插件列表。另一個(gè)關(guān)于免費(fèi) Maven 插件的較佳資源是 SourceForge 上的 Maven 插件項(xiàng)目。(以上各項(xiàng)的鏈接可在 參考資料中獲得)。

    如果仍不能找到符合您要求的 goal,Maven 給您兩種選擇:

    • 編寫 <preGoal><postGoal> 來擴(kuò)展標(biāo)準(zhǔn) goal
    • 編寫自己的 goal

    無論選擇哪種,都要在項(xiàng)目目錄中創(chuàng)建名為 maven.xml 的特殊文件。清單 6 顯示了框架 maven.xml。


    清單 6. 框架 maven.xml
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <project xmlns:j="jelly:core">
            ...
            <goal name=...>
              ... build rules, e.g.
              <mkdir dir="${test.result.dir}"/>
              <echo>Executing JUnit tests</echo>
              ...
            </goal>
            ...
            <preGoal name=...>
              ...
            </preGoal>
    
            <postGoal name=...>
              ...
            </postGoal>
    
          </project>
    

    熟悉 Ant 的開發(fā)人員會發(fā)現(xiàn) Maven 的 goal(同樣還有 preGoalpostGoal )可在其定義中包含任何有效的 Ant 任務(wù),這有助于快速學(xué)習(xí) Maven 并保護(hù)在 Ant 上的投入。為了給 Ant 任務(wù)添加動態(tài)性,Maven 也使用 Jelly 腳本編制語言。“ 基礎(chǔ) Jelly 編程”用一個(gè)樣本 maven.xml 文件介紹 Jelly 腳本編制語言。

    編寫 <preGoal> 和 <postGoal>
    Ant 的 <target>makefile 規(guī)則的相似之處在于:定義了規(guī)則以后,前提條件和后置條件是固定的。這使得在多個(gè)項(xiàng)目間重用構(gòu)建規(guī)則變得更加困難。例如,某個(gè)項(xiàng)目中的 compile target 可能依靠 XDoclet 生成源文件,而另一個(gè) compile target 可能不包括任何先決條件。為了克服這種限制,Maven 提供了兩個(gè)特殊標(biāo)記: <preGoal><postGoal> 。從標(biāo)記的名稱可以看出: preGoal 定義在指定的 goal 之前執(zhí)行的構(gòu)建規(guī)則。另一方面, postGoal 定義實(shí)現(xiàn)指定 goal 之后要執(zhí)行的構(gòu)建規(guī)則。例如,清單 7 中的 preGoal 指示 Maven 在編譯源代碼之前用 XDoclet 生成源文件。


    清單 7. 樣本 preGoal 部分
            <preGoal name="java:compile">
              <attainGoal name="xdoclet:ejbdoclet"/>
            </preGoal>
    

    Maven 還提供與 Ant 的 <antcall> 標(biāo)記相似的 <attainGoal> 標(biāo)記,以便在確有必要直接實(shí)現(xiàn) goal 的情況(如上例)下使用。

    編寫自己的 goal
    如果 goal 是特定于項(xiàng)目的,則可在 maven.xml 文件中定義自己的 goal。這些自定義的 goal 會覆蓋其它同名的 goal。如果項(xiàng)目包括子項(xiàng)目,子項(xiàng)目也繼承這些 goal。

    編寫插件
    為了在項(xiàng)目間共享 goal,可在 Maven 安裝插件目錄( ${MAVEN_HOME}/plugins )中將其打包為插件。典型的 Maven 插件包含 project.xml 和 plugin.jelly 文件。project.xml 文件描述插件的 POM;plugin.jelly 類似 maven.xml 且包含該插件所展示的 goal。插件可以有自己的資源和相關(guān)性信息。預(yù)先定義的變量 ${plugin.dir} 讓用戶引用插件目錄中的資源。例如,在清單 8 中所示的插件結(jié)構(gòu)中, ${plugin.dir}/dtd/web-app_2_3.dtd 可訪問 plugin.jelly 中的 web-app_2_3.dtd


    清單 8. 樣本插件結(jié)構(gòu)
        ejbjar-plugin-1.0
        |-- dtd
        |   |-- application_1_3.dtd
        |   |-- ejb-jar_2_0.dtd
        |   |-- web-app_2_3.dtd
        |-- plugin.jelly
        `-- project.xml
    



    回頁首


    安裝 Maven

    最近發(fā)行的 Maven 1.0-beta-8 基本上是 1.0 的功能完善版。因?yàn)?Maven 開發(fā)社區(qū)每天都在修正錯(cuò)誤,如果您遇到任何無法正常工作的問題,則立即從 CVS(Concurrent Version System,并發(fā)版本控制系統(tǒng))獲得最新 Maven 版本,然后自行構(gòu)建(請參閱 參考資料以獲得指示信息)。下載了最新的 Maven 源代碼之后,可通過調(diào)用以下命令來構(gòu)建 Maven:

          ant -f build-bootstrap.xml
    
          (set MAVEN_HOME to where you want Maven to reside and
          use Ant 1.5.1 to perform the build)
    

    如果在防火墻之后操作,請正確設(shè)置以下特性: maven.proxy.hostmaven.proxy.portmaven.proxy.usernamemaven.proxy.password 。缺省情況下,Maven 資源庫駐留在 ${MAVEN_HOME}/repository 中;通過將 maven.repo.local 特性設(shè)置為新位置,可以更改 Maven 資源庫的位置。

    樣本項(xiàng)目文件

    請參閱在這個(gè)樣本 J2EE 項(xiàng)目中使用的 Maven 項(xiàng)目文件



    回頁首


    樣本 J2EE 項(xiàng)目

    掌握了到目前為止所學(xué)的知識后,就可以著手使用 Maven 了。本節(jié)描述如何用 Maven 設(shè)置一個(gè)樣本 J2EE 項(xiàng)目。

    項(xiàng)目目錄布局

    在進(jìn)行詳細(xì)介紹之前,我先說明一下項(xiàng)目的目錄布局。盡管不作要求,但事實(shí)證明一致的跨項(xiàng)目目錄布局非常有用,因?yàn)槭煜ち艘粋€(gè)項(xiàng)目的開發(fā)人員可以輕松地瀏覽其它項(xiàng)目。更重要的是,一致的目錄布局可讓您編寫通用的構(gòu)建規(guī)則。

    Maven 的目錄布局指南(請參閱 參考資料)適用于絕大多數(shù)項(xiàng)目。作為演示,我使用略微不同的布局,如清單 9 所示。


    清單 9. 樣本項(xiàng)目目錄布局
     project
     |
     |-- LICENSE.txt
     |-- project.properties
     |-- maven.xml
     |-- project.xml
     |-- src
     |   `-- java
     |       `-- com/....
     |   `-- conf
     |       `-- Configuration files for staging environments.
     |-- test
     |   `-- java
     |       `-- com/....
     |   `-- conf
     |       `-- Configuration files for unit testing environments.
     `-- xdocs
         `-- index.xml
    

    一個(gè) J2EE 項(xiàng)目通常生成 WAR 文件、EJB JAR 文件和 EAR 文件。因?yàn)槊糠N文件都包括自己的相關(guān)性信息和源文件,所以應(yīng)將其作為單獨(dú)項(xiàng)目來構(gòu)建。通常,通過將子項(xiàng)目存儲為主項(xiàng)目的子目錄,來構(gòu)造這一項(xiàng)目/子項(xiàng)目關(guān)系。我們的布局如清單 10 所示。


    清單 10. Maven 中 J2EE 項(xiàng)目的高級目錄布局
    j2ee-project
    |
    |-- project.xml       - Produces the EAR file
    |
    |-- util-subproject
    |   |
    |   `-- project.xml   - Produces the Utility JAR file
    |
    |-- ejb-subproject
    |   |
    |   `-- project.xml   - Produces the EJB JAR file
    |
    `-- web-subproject
        |
        `-- project.xml   - Produces the WAR file
    

    項(xiàng)目繼承

    項(xiàng)目繼承讓 POM 以類似于對象繼承的方式從主 POM 繼承 ― 由于這些項(xiàng)目之間的細(xì)微差別(主要是相關(guān)性的差別),這一特性在此尤為重要。項(xiàng)目管理部分可在主 project.xml 中集中維護(hù)。要使用項(xiàng)目繼承,可使用 project.xml 中的 <extend> 標(biāo)記(請參閱“ 樣本項(xiàng)目文件”中的清單 2)。

    樣本項(xiàng)目的 goal

    既然已經(jīng)定義了 POM,就可以編寫它們的 goal。因?yàn)檫@些 goal 使用 POM 中定義的特性,所以在繼續(xù)之前應(yīng)該首先理解“ 樣本項(xiàng)目文件”中的 project.xml 文件。

    Utility 子項(xiàng)目

    由于 Utility 子項(xiàng)目生成一個(gè)包含源目錄中類的 JAR 文件 ― 由缺省的 jar:jar goal 即可滿足要求,因此這里不需要定制的 goal。

    因?yàn)?Web 子項(xiàng)目和 EJB 子項(xiàng)目都依靠 Utility 子項(xiàng)目,所以,在構(gòu)建 Web 子項(xiàng)目和 EJB 子項(xiàng)目之前,應(yīng)該調(diào)用 jar:install goal 以將 Utility 子項(xiàng)目 JAR 文件部署到本地資源庫。這樣,WAR 子項(xiàng)目和 EJB 子項(xiàng)目就可以正確地解析相關(guān)性。

    Web 子項(xiàng)目

    Web 子項(xiàng)目生成一個(gè) WAR 文件,該文件包含源目錄的類、 jsp 目錄中的 JSP 文件和 conf 目錄中的 web.xml 文件。缺省 war:war goal 有更簡單的關(guān)于項(xiàng)目目錄布局的視圖。要重用該 goal,可如下定制其行為:

    1. 在項(xiàng)目的 project.properties 文件中,將特性 maven.war.srcmaven.war.webxml 分別設(shè)置為 ${maven.build.dir}/webapp${maven.src.dir}/conf/web.xml 。這告訴 war:war 在哪里查找 Web 來源(JSP 頁面、HTML 靜態(tài)頁面和圖像等)和 web.xml 文件。
    2. 定義一個(gè)將所有 JSP 文件復(fù)制到 ${maven.build.dir}/webapp 目錄中的 preGoal 。以下 maven.xml 可實(shí)現(xiàn)這一效果:

      <?xml version="1.0" encoding="ISO-8859-1"?>
      <project>
      
        <preGoal name="war:init">
          <copy todir="${maven.build.dir}/webapp">
            <fileset dir="${maven.src.dir}/jsp" include="*.jsp"/>
          </copy>
        </preGoal>
      
      </project>
      

    當(dāng)調(diào)用 war:war goal 時(shí),請注意 Utility JAR 文件和 commons-beanutils JAR 文件都被打包到 WAR 文件。通過查看 project.xml 文件的相關(guān)性部分中的 war.bundle.jar 特性,Maven 知道要在 WAR 文件中包括哪個(gè)文件。

    EJB 子項(xiàng)目

    給 EJB JAR 文件打包和給 JAR 文件打包相似。如果項(xiàng)目設(shè)置與缺省 ejb goal 不匹配,可應(yīng)用以上“Web 子項(xiàng)目”一節(jié)中所描述的技術(shù)。在這個(gè)特定例子中,將 ejb-jar.xml 從 conf 目錄復(fù)制到 ${maven.build.dir}/ejb/META-INF 目錄,并將 maven.ejb.src 特性設(shè)置為 ${maven.build.dir}/ejb

    要將相關(guān)性 JAR 文件添加到 EJB JAR 的清單類路徑(manifest classpath)中,可在相關(guān)性部分中使用 ejb.manifest.classpath 特性。

    主(EAR)項(xiàng)目

    在成功編譯并部署了子項(xiàng)目(使用 jar:installwar:installejb:install goal)之后,即可創(chuàng)建最終的 EAR 文件。相關(guān)性特性 ear.bundle.jarear.bundle.ejbear.bundle.war 告訴 ear 插件要在 EAR 文件中包括哪些文件。(對于 Maven 1.0-beta-8,WAR 文件不是受支持的相關(guān)性類型,因此 EAR 插件不能正確地給 WAR 文件打包。解決辦法:使用 postGoal 手工更新 EAR 文件。)

    reactor:自動構(gòu)建子項(xiàng)目

    構(gòu)建 J2EE 項(xiàng)目需要大量的工作。事實(shí)證明,每次項(xiàng)目更改時(shí)重復(fù)同樣的過程耗費(fèi)時(shí)間而且容易出錯(cuò)。為幫助解決這些問題,Maven 的 reactor 功能部件以正確的順序自動構(gòu)建子項(xiàng)目,這樣就節(jié)省了時(shí)間且減少了錯(cuò)誤。

    清單 11 的 maven.xml 演示了定義 reactor 的方法。


    清單 11. 樣本 reactor 定義
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <project default="all"
             xmlns:m="jelly:maven">
    
      <goal name="all">
        <m:reactor basedir="${basedir}"
                   includes="*/project.xml"
                   goals="install"
                   banner="Building"
                   ignoreFailures="false"/>
      </goal>
    </project>
    

    該 reactor 首先在 basedir 目錄下搜索 project.xml 文件,然后調(diào)用 install goal。執(zhí)行的順序取決于每個(gè)項(xiàng)目中的相關(guān)性部分。此外,通常可以在主項(xiàng)目的 maven.xml 文件中定義 reactor。因?yàn)?goal 在子項(xiàng)目中繼承,所以選擇 goal 的名稱時(shí)要當(dāng)心。



    回頁首


    參與其中

    盡管 Maven 是功能豐富的產(chǎn)品,但它仍處于 beta 測試版階段。因此錯(cuò)誤可能在任何地方突然出現(xiàn)。別慌。要找到解決錯(cuò)誤的答案,最好的辦法是搜索 Maven 的郵件列表歸檔(請參閱 參考資料)以了解相關(guān)的通告。如果沒有任何發(fā)現(xiàn),試著將問題公布到郵件列表,以便得到別人的建議。郵件列表上列出的人一般都樂于給予幫助。

    要正式地報(bào)告錯(cuò)誤,請?jiān)L問 Maven 項(xiàng)目的問題跟蹤系統(tǒng)(請參閱 參考資料)。

    一旦熟悉了 Maven,您可能會在插件的實(shí)現(xiàn)中找到絕大多數(shù)答案。當(dāng)您達(dá)到專家水平并且相信 Maven 大有前途的時(shí)候,請向社區(qū)提供補(bǔ)丁,幫助 Maven 成長。



    回頁首


    結(jié)束語

    隨著如今的項(xiàng)目變得越來越復(fù)雜,我們需要能幫助我們表示并管理這些復(fù)雜性的工具。Maven 將項(xiàng)目對象模型與功能強(qiáng)大的 XML 腳本編制語言相結(jié)合,為我們提供了這樣的工具。在本文中,您已經(jīng)了解如何定義 POM 以及如何使用 Maven 的 goal 機(jī)制構(gòu)建項(xiàng)目。我們還研究了使用 Jelly 定制構(gòu)建行為的不同方法。最后,利用一個(gè)樣本 J2EE 項(xiàng)目,我們將概念在實(shí)際中加以應(yīng)用。希望您下載 Maven 以推動其發(fā)展。

    作者感謝 Jason van Zyl 對本文的評審。



    回頁首


    參考資料



    回頁首


    關(guān)于作者

    Charles Chan 是 Finetix LLC 的一名顧問。Charles 的興趣包括分布式系統(tǒng)、高性能計(jì)算、國際化和軟件設(shè)計(jì)模式。在業(yè)余時(shí)間,他為開放源碼社區(qū)撰稿。可以通過 charlesc@ibiblio.org 與 Charles 聯(lián)系。

    posted on 2006-02-09 14:52 TrampEagle 閱讀(505) 評論(0)  編輯  收藏 所屬分類: opensource
    主站蜘蛛池模板: 亚洲欧洲日产专区| 亚洲综合色成在线播放| 青青青国产在线观看免费网站| 成在人线av无码免费高潮喷水 | 国产91精品一区二区麻豆亚洲| 国产成人免费a在线视频app | 日韩成人免费在线| 成人免费毛片内射美女APP| 国产一卡2卡3卡4卡无卡免费视频 国产一卡二卡3卡四卡免费 | AV在线亚洲男人的天堂| 久久亚洲2019中文字幕| 亚洲综合伊人久久大杳蕉| 亚洲日韩欧洲乱码AV夜夜摸| 成人黄软件网18免费下载成人黄18免费视频| 很黄很黄的网站免费的| 岛国大片免费在线观看| 免费大片黄手机在线观看| 国产亚洲精品资在线| 国产亚洲无线码一区二区| 亚洲精选在线观看| 亚洲国产亚洲综合在线尤物| 亚洲性色精品一区二区在线| 亚洲日本在线观看| 亚洲大尺码专区影院| 亚洲精品美女久久久久久久| 亚洲一区二区三区亚瑟| 亚洲av激情无码专区在线播放| 1区1区3区4区产品亚洲| 色在线亚洲视频www| 国产成人不卡亚洲精品91| 国产高清视频免费在线观看| 99久久人妻精品免费二区| 男男AV纯肉无码免费播放无码 | 日本一卡精品视频免费| 歪歪漫画在线观看官网免费阅读 | 最近中文字幕高清免费中文字幕mv| 久久久久久国产a免费观看黄色大片| 精品免费国产一区二区三区| 久久激情亚洲精品无码?V| 亚洲黑人嫩小videos| 亚洲第一综合天堂另类专 |