<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

    發表于 2007-3-19 12:45

    用 Maven 做項目管理 Java世界中我們很多的開發人員選擇用 Ant來構建項目,一個 build.xml能夠完成編譯、測試、打包、部署等很多任務,但我們也碰到了很多的問題,如 jar文件管理混亂,各個項目結構和 build.xml相差很大等等。而 Maven的出現,給項目提供了更多的支持。



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

    2        項目管理 Maven 官方把 maven 定義為一個項目管理工具,我們不妨看看 maven 能給我們的項目提供哪些好的支持。
    2.1       項目標準化 Maven 一個重要特性是定義了項目的標準模板,官方說法是最佳實踐。可以通過命令: mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app 創建一個單一的 maven 項目。創建好的項目,具有了特定的項目結構。這個項目結構是參考業界的最佳實踐而成,為后面使用統一的 maven 命令打下了基礎,如測試 mvn test 、打包 mvn package 等,無需寫一行腳本,就可以方便的實現眾多功能。 Maven 還提供其它一些類型模板,可以通過添加 -DarchetypeArtifactId= type }創建,如 -DarchetypeArtifactId=maven-archetype-site ,生成 site 類型的項目。
    同時一些好的開源軟件使用了 maven ,也能作為很好的項目模板,如 Equinox Appfuse 的簡化版),它的 pom 定義了對 hiberante,spring… 的依賴,可以通過 ant new -Dapp.name=NAME 快速生成項目原型,然后對 pom 文件進行裁減,以符合自身項目的需要。
    有了這個標準,項目間能方便的進行交流,你也很容易了解其它使用 maven 項目的結構。對于企業來說,引入 maven 就自然引入了規范,這可比費時費力的寫文檔,定規范有效的多了。
    2.2       文檔和報告 使用 mvn site 可以快速生成項目站點, apache 很多開源項目站點都采用 maven 生成,會出現 built by maven 字樣的圖標。
    maven 提供的針對如 junit checkstyle pmd 等的插件,能夠方便的進行測試和檢查并能直接生成報告。使用都很簡單,如 mvn surefire-report:report 就能自動進行 junit 測試,并生成 junit 報告, mvn pmd:pmd 生成 pmd 報告。具體使用可以在 http://maven.apache.org/plugins/index.html 找到。
    2.3       類庫管理 Maven 一個很重要的特色就是類庫管理。通過在 pom.xml 中定義 jar 包版本和依賴,能夠方便的管理 jar 文件。以下是一個簡單的 jar 定義片斷:
    <dependency>                                                                       
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate</artifactId>
          <version>3.1</version>
          <type>jar</type>
          <scope>runtime</scope>
      </dependency>
    這個片斷告訴我們,依賴的 jar groupId org.hibernate artifactId hibernate ,版本為 3.1 scope runtime 。在實際項目中,會將 M2_REPO(maven 本地倉庫地址 )/ org/hibernate / hibernate /3.1/ hibernate -3.1.jar 放入 classpath
    同時 maven 會通過 pom.xml 管理 jar 包間的依賴。比如上面的 hibernate-3.1.jar 同級目錄肯定會有一個 hibernate -3.1.pom ,在這個 pom 文件中指定了這個 jar 對其它一些 jar 的依賴。而這個 pom 文件是遠程倉庫提供,無需進行修改,執行 maven 相關命令就會自動根據相關依賴去下載 jar 包。這樣只需定義對 hibernate 的依賴而無需關心相關 jar ,在構建項目上方便了很多。
    因為 pom 文件對 jar 的管理,也產生了一個很吸引人的特性:項目文件很小。以往一個 web 項目中, jar 文件都要放入 WEB-INF/lib 下,并放入 cvs(svn) 中,很容易就達到幾十 M 。而通過 maven ,只需一個 pom.xml ,在執行 mvn eclipse:eclipse 時再去遠程倉庫下載,項目文件一般只需幾百 K
    2.4       發布管理 使用 maven 可以方便的進行項目發表管理。在項目開發到一定階段,可以使用 mvn package 打包,它會自動先運行 mvn test ,跑所有的 testcase ,只有全部通過才能正確打包。生成的 war 包(如果項目的 packaging war )在 target 目錄下。這個 war 包與使用 ant 腳本生成一樣,但無需一行腳本,這也是 maven 對比 ant 的優勢之一。使用 mvn install 將編譯和打包好的文件發布到 distributionManager 指定的遠程 repository 。使用 mvn deploy 可以自動管理項目版本。
      
    3         使用 maven Maven 使用簡單,插件豐富且經過大量項目考驗,在項目中引入的風險很小。筆者在項目中使用 maven ,新進員工在半小時內就能成功使用 maven 構建項目,并很快掌握幾個常用的命令。 Maven 也不需要什么特殊的設施。如果項目全部使用開源軟件,并且不需要 maven 管理項目版本,只需要一個 SCM 環境( CVS SVN ),共享開發源碼就可以。把 pom.xml 中的 repository 設為官方地址就行,配置如下:
    <repository>
          <id>central</id>
          <url>http://www.ibiblio.org/maven2</url>
    </repository>
    這個官方 remote repository 上有非常多的開源軟件,應該能滿足大部分項目的需要。如果有項目需要而它上面暫時還沒有的軟件,或者希望使用公司內部的軟件,那么就需要自己配置一個 repository 了。
    3.1       自建私服 傳奇私服大家應該都聽過,一個網吧自己搞個私服,一伙人免費在上面砍殺。官方因此少賺了很多錢,因此總想打擊。而 maven 官方卻對自建私服很是支持,我們總算可以正正當當搞把私服了( Springside 的老大江南白衣就是創建私服的好手)。我們就來介紹下自建私服的最快方法。
    首先需要一個 http server ,找臺服務器裝上 apache 就行。放一個空的 maven 目錄到 htdocs 下,假設服務器 ip 192.168.0.1 ,確認能用 http://192.168.0.1/maven 訪問到。然后在自己機器上裝好 maven2 ,初始化好項目,在 pom.xml 放入需要的 jar 定義,運行如 mvn eclipse:eclipse 就自動從官方下載 jar 到本地,如果不做配置,默認本地 repository ${user.home}/.m2/ 。對于 windows xp 來說一般在 C:\Documents and Settings\ username%\.m2 下,其中% username %為操作系統登錄用戶名。這時你可以看到 ${user.home}/.m2/ 下多了個 repository 目錄,里面有很多的項目相關 jar ,目錄按 groupId/ artifactId/version 排好。把 repository 目錄整個拷貝到 apache 服務器的 maven 目錄下,如果需要官方缺少的 jar 或公司內部 jar ,仿照這個目錄結構,做好 jar 放到 maven 目錄下。自建私服成功!
    要使用私服,只需修改 pom.xml ,在 repository 配置后加上:
    <repository>
          <id>companyName</id>
          <url>http:// ${ip}/maven</url>
    </repository>
    這樣需要下載 jar 時,會先到本地 repository 查看,沒有下載過再到官方搜索,沒有找到再到后面的 repository 查找。
    3.2       安裝配置 Maven 的安裝很簡單:
    1.          apache 網站上下載 maven 安裝包,實際上就是個壓縮文件。將其解壓到你想要存放 maven 的目錄中。在這里假設你將 maven 解壓到 C:\Program Files\Apache Software Foundation\maven-2.0.4 中。
    2.       C:\Program Files\Apache Software Foundation\maven-2.0.4\bin 設到你的系統環境變量%PATH%中。
    3.       同時確保你已經將你的JDK安裝目錄設為java_home系統變量。
    4.         打開個命令行窗口,運行 mvn –version 驗證是否安裝成功。
    5.         如果使用 eclipse ,在運行 mvn eclipse:eclipse 生成 eclipse 項目文件后,需加入 M2_REPO Classpath Variables 中,指向 本地 repository ,例如: C:/Documents and Settings/Owner/.m2/repository
    3.3       基本使用流程 在項目進程中,不必做什么配置,在 pom.xml 同級目錄, cmd 使用簡單的 maven 命令,就可以完成初始化 -> 開發 -> 測試 -> 發布 的全過程。 Maven 的基本使用流程如下圖:

    其中在初次使用命令 mvn eclipse:eclipse 時會下載很多的插件和 jar ,可能需要較長的時間,建議泡杯咖啡,和同事吹吹牛。如果失敗,可能是網絡問題,可以重新運行 mvn eclipse:eclipse ,已下載好的插件和 jar 不會再下。運行 mvn test mvn package 等命令,產出物都會放在 target 目錄下。如果在使用過程中有什么問題,也可以和我聯系, mail:pesome@gmail.com ,我們一起來嘗試解決。
      
    總結:
    Maven 作為新的項目管理工具,簡單易用,能對項目的各個階段提供大力支持,同時由于它易擴展的插件體系架構,出現了越來越多的插件,也使得其功能更加強大。短短一篇文章,實在很難把其特點一一盡述, maven 還有很多好用的功能和插件等待我們去使用和開發。而學習新技術的最好方式就是實踐,大家如果有興趣,盡快下載一個最新版,開始你的 maven 之旅吧!
      
    作者簡介:張俊,網名 pesome ,上海交大軟件工程碩士, 2 JavaEE 開發經驗,資歷尚淺。去年下半年開始接觸 spring 等開源軟件,并產生了濃厚的興趣。今年 3 月開始做 www.openfans.net ,用一堆開源軟件搭建而成,希望為中國的開源事業做出一點貢獻。
      
    參考文檔:
    1.       http://maven.apache.org 官方網站文檔
    2.       http://www-128.ibm.com/developerworks/cn/opensource/os-maven2/ Maven2 的新特性


    Posted by kevinwu on December 15, 2006 09:22 PM | 全文 |MAVEN|del.icio.us|VIVI|365key|blogChina|Poco|SOHU|Hexun

    相關文檔_
    使用Maven構造Turbine項目 - Dec 15, 2006
    Maven 讓事情變得簡單 - Dec 15, 2006
    在 Eclipse 中利用 Maven - Dec 15, 2006
    maven2.0學習筆記(轉載) - Dec 15, 2006
    Maven入門--概念與實例(轉載) - Dec 15, 2006


    null

    發表于 2007-3-19 12:40

    Maven入門--較復雜的實例

    本文將使用一個較復雜的實例,講述如何定制目錄布局(即不使用Maven標準目錄布局),以及講述一些關鍵插件的使用(配置)。為了方便其它朋友能夠方便地使用該實例,后臺數據庫使用開源的面向對象數據庫--db4o,該數據庫無需安裝,已包含在與本文配套的實例中,文末附有該實例的下載鏈接。(2007.01.02最后更新)

    1 實例的構想
    文章開頭的摘要已經講述了,本文仍然將以一個實例描述如何使用Maven,
    該實例將使用非Maven標準的目錄結構,并將呈現一些關鍵的Maven插件的配置與應用。 該實例是一個基于db4o的數據庫Web應用。該應用本身十分簡單,即從db4o數據庫中查詢出若干記錄并將它們顯現在Web頁面中。
        該實例仍然由一個普通應用工程(demo-app)與一個Web應用工程(demo-web),以及這兩個工程的父工程(demo)構成,最終的目標是將 Web應用工程制作成war文件,并部署到JBoss服務器中。啟動服務器后,能夠在頁面中看到正確的查詢結果。
        該實例使用Eclipse3.2 + JDK1.5.0_10 + Windows2000開發。當然這僅僅只是我個人的開發平臺,但該實例并不受限于此平臺;由于我選擇使用db4o針對JDK1.5的產品包,所以該實例只能運行在JDK1.5.0或更高版本的JDK/JRE中; 該工程中的所有文件都使用UTF-8編碼方式。

    2 demo工程
    demo工程是其它兩個工程的父工程,它的主要職責是預定義子工程所需要依賴的jar文件(artifact),以及針對子工程所使用的插件進行通用配置。該工程完整的POM文件如下所示:
    [size=+0][size=+0][size=+0]<project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>mvn.demo</groupId>
        <artifactId>demo</artifactId>
        <packaging>pom</packaging>
        <version>
    1.0-SNAPSHOT</version>
        <description>Maven Demo Project</description>

        <modules>
            <module>demo-app</module>
            <module>demo-web</module>
        </modules>

        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>mvn.demo</groupId>
                    <artifactId>demo-app</artifactId>
                    <version>${project.version}</version>
                </dependency>
                <dependency>
                    <groupId>mvn.demo</groupId>
                    <artifactId>demo-web</artifactId>
                    <version>${project.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.db4o</groupId>
                    <artifactId>db4o-java5</artifactId>
                    <version>
    5.5</version>
                </dependency>
                <dependency>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                    <version>
    2.4</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>commons-configuration</groupId>
                    <artifactId>commons-configuration</artifactId>
                    <version>
    1.2</version>
                    <exclusions>
                        <exclusion>
                            <groupId>dom4j</groupId>
                            <artifactId>dom4j</artifactId>
                        </exclusion>
                        <exclusion>
                            <groupId>xml-apis</groupId>
                            <artifactId>xml-apis</artifactId>
                        </exclusion>
                        <exclusion>
                            <groupId>xalan</groupId>
                            <artifactId>xalan</artifactId>
                        </exclusion>
                        <exclusion>
                            <groupId>xerces</groupId>
                            <artifactId>xercesImpl</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
            </dependencies>
        </dependencyManagement>

        <dependencies>
            <dependency>
            <groupId>junit</groupId>
             <artifactId>junit</artifactId>
               <version>
    3.8.1</version>
          <scope>test</scope>
        </dependency>
        </dependencies>

        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-
    8</encoding>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>
    1.5</source>
                        <target>
    1.5</target>
                        <encoding>UTF-
    8</encoding>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <configuration>
                        <archive>
                            <addMavenDescriptor>false</addMavenDescriptor>
                        </archive>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <configuration>
                        <archive>
                            <addMavenDescriptor>false</addMavenDescriptor>
                        </archive>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <configuration>
                        <charset>UTF16</charset>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">

        預定義工程的依賴關系,就是把會被子工程依賴的artifact的詳細信息(groupId,artifactId,version,...)先聲明到 <dependencyManagement>中。然后子工程只需要聲明使用某個artifact就可以了,即那時只需要設置groupId 和artifactId(甚至更少)就可以了。 <dependencyManagement>中聲明的artifact并不一定真的會被使用到
    2.1 聲明依賴關系
        根據實際情況,
    該實例 需 要使用db4o針對java5的產品包(jar文件)。由于該jar文件并不存在于Maven的中央倉庫中,所以我們不能直接通過Maven獲得該jar 文件。我們只能另外下載db4o-5.5(Java版)的壓縮包,然后從壓縮包內獲得db4o-java5.jar。得到該jar后,必須先將它安裝到 Maven的本地倉庫中(安裝方法參見資源[1],主題"向本地倉庫安裝文件時要生成POM文件"),以備后面的使用。此處將該artifact的 groupId定義為com.db4o,artifactId定義為db4o-java5,version自然就是5.5了(請見上述POM腳本)。
        由于該實例最終是一個Web應用,所以它至少需要依賴Servlet的包(servlet-api-2.4.jar),還需要commons- configuration-1.2.jar。這兩個artifact都已經存在于Maven中央倉庫中,所以我查找到它們后,按照Maven中央倉庫的 命名將它們聲明到了<dependencyManagement>中(請見上述POM腳本)。junit是進行單元測試時使用的 artifact,(假設)它肯定會被每個工程使用,所以沒有將它設置到 <dependencyManagement>中,而直接設置到了 <dependency>中。
        細心的朋友肯定已經發現了,針對 commons-configuration的依賴聲明處多了一些語句。從表面上看,應該是排除了4個artifact(dom4j, [size=+0]xml-apis [size=+0]xalan [size=+0]xerces )。 不錯,就是排除了這4個jar文件(artifact)。如果有興趣的話,可以將整個<exclusions>元素刪除,然后再嘗試一下制作 war文件。你會發現在WEB-INF/lib目錄下存在著這4個artifact對應的jar文件。那我為什么要將它們“排除”呢?因為,它們是多余 的!即,它們對于我的這個Web應用來說,根本就是無用的!
        Maven2加入了一個很好的特性:自動加載“依賴的依賴(Transitive Dependency)”。 以commons-configuration為例。為了能夠讓它運行正常,我們實際上還需要其它一些jar(artifact),如commons- collections,commons-lang,...。但這些artifact我都沒有“顯示”地聲明需要依賴它們,但Maven會自動加載,因為
    commons-configuration的POM文件將它們聲明為了dependency
        既然那個4個artifact是commons-configuration的依賴,為什么會認為它們是無用的呢?實際上,它們就不應該被聲明到commons-configuration的依賴關系中。這是commons -configuration開發者的失誤,他們沒有將依賴關系整理清晰,而將一些確實既不是runtime,更不是compile-time需要的 artifact放入到了依賴關系中。在Maven中央倉庫中存在著很多這種情況,所以我們有時需要弄清楚“哪些文件是我們真正需要的,哪些是可以被清除 的”。但有時候,很難做到一個不漏。正是由于這一原因,自動加載Transitive Dependency這一極好的特性,有時讓人十分無奈 ^_^
    2.2 對插件進行基本配置
    我們可以把對插件的全局性(如針對整個項目的)設置放到較高層次的POM文件中,因為它們被設置后,子工程們就會自然遵守它們,而且可以使每個子工程的情況都是一樣的。
        在第1節中,已經表明該工程使用JDK1.5平臺,并且所有文件都使用UTF-8
    的編碼方式。而Maven默認使用JDK1.3級別的javac編譯器;默認使用本地編碼方式(簡體中文Windows操作系統默認使用GBK編碼方式)處理文件。這樣就必須對Maven進行適當設置,以滿足工程的實際需要。
        針對資源文件的處理,Maven使用maven- resources-plugin插件,需要將它的編碼方式設置為UTF-8。編譯Java源文件,是使用maven-compiler-plugin插 件,需要將它的source(Java源文件)與target(class文件)的級別都設置為1.5,另外還要將它的encoding方式設置為UTF -8。(詳細設置請見POM腳本)

    3 demo-app工程
    demo-app工程是一個普通應用程序工程,它用于處理和數據庫相關的操作,如針對數據庫的增、刪、改、查等基本功能。該工程POM文件的主要內容如下所示:
    <project>
        ......

        <build>
            <finalName>app</finalName>
            <directory>target</directory>

            <sourceDirectory>src/java</sourceDirectory>
            <outputDirectory>target/classes</outputDirectory>
            <resources>
                <resource>
                    <directory>src/java</directory>
                    <excludes>
                        <exclude>**/*.java</exclude>
                    </excludes>
                </resource>
            </resources>

            <testSourceDirectory>src/test/java</testSourceDirectory>
            <testOutputDirectory>target/test-classes</testOutputDirectory>
            <testResources>
                <testResource>
                    <directory>src/test/java</directory>
                    <excludes>
                        <exclude>**/*.java</exclude>
                    </excludes>
                </testResource>
            </testResources>
        </build>
    </project>

        文章的開頭已經提到,本實例將會使用定制的目錄結構,但在前面卻一字不提此事,現在將描述如何定制目錄結構。Maven的標準目錄結構其實是在Super POM中設置的,由于任何POM都會繼承該POM,所以所有的工作都會默認使用標準目錄結構。要定制目錄,其實就是需要重新設置相關參數的值,即用新值覆 蓋Super POM中的值。
    [size=+0][size=+0][size=+0][1]<finalName>,該元素指定了工程輸出的artifact的名稱,默認值為${artifactId}-${version},此處修改為app。
    [size=+0][size=+0][size=+0][2]<directory>,該元素指定了工程輸出的目標目錄。默認值為target,此處未修改變。
    [size=+0][size=+0][size=+0][3]<sourceDirectory>,該元素指定了Java源文件所在的目錄。默認值為src/main/java,此處修改為src/java。
    [size=+0][size=+0][size=+0][4]<outputDirectory>,該元素指定了編譯后的class文件的放置目錄。默認值為target/classes,此處未作改變。
    [size=+0][size=+0][size=+0][5]<resources> [size=+0][size=+0][size=+0]< resource>,該元素指定了Java源文件使用的資源文件的存放目錄。默認值為src/main/resources,此處修改為 src/java。由于在編碼Java源文件時,Maven會將資源路徑中的文件全部拷貝到classes目錄。而此時將Java資源文件目錄與Java 源文件目錄,設置為同一目錄,所以需要將.java文件排除在資源文件的范疇之外( [size=+0][size=+0][size=+0]<exclude>**/*.java</exclude> [size=+0][size=+0][size=+0])。
    [6]
    [size=+0][size=+0][size=+0]<testSourceDirectory>,該元素指定了單元測試Java源文件的放置目錄。默認值為src/test/java,此處未作修改。
    [7]
    [size=+0][size=+0][size=+0]<testOutputDirectory>,該元素指定了單元測試Java源文件編譯后的class文件放置目錄。默認值為 [size=+0][size=+0][size=+0]target/test-classes,此處未作改變。
    [8]
    [size=+0][size=+0][size=+0]<testResources> [size=+0][size=+0][size=+0]<testResource>,該元素指定了單元測試Java源文件所使用的資源文件的放置目錄。默認值為src/test/resources,此處修改為 [size=+0][size=+0][size=+0]src/test/java。并且也做了與 [size=+0][size=+0][size=+0]設置<resources> [size=+0][size=+0][size=+0]<resource>時相同的處理(排除Java源文件)。
        通過上述設置后,就可以擁有一個定制的Maven工程目錄結構了。

    4 demo-web工程
    demo-web工程是整個應用最終的目標輸出,因為此處的目的就是制作一個war文件,然后將它部署到JBoss服務器中。與demo-app工程相比,demo-web工程的POM文件主要有如下不同內容:
    <project >
        ......
        <build>
            ......
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>
    2.0.1 </version>
                    <configuration>
                        <webappDirectory>target/${artifactId}</webappDirectory>
                        <warSourceDirectory>src/webapp</warSourceDirectory>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>jboss-maven-plugin</artifactId>
                    <version>
    1.3.1 </version>
                    <configuration>
                        <jbossHome>E:/jboss-
    4.0.2 </jbossHome>
                        <serverName>default</serverName>
                        <fileName>
                            ${project.build.directory}/${project.build.finalName}.${project.packaging}
                        </fileName>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>

    可以看出不同之處就在于對maven-war-plguin及jboss-maven-plugin插件的配置與使用。
        Maven使用maven-war-plugin插件對Web工程制作war文件。由于本文使用了定制目錄結構,這樣則會使maven-war- plugin無法找到Web工程的Web Root目錄(默認是src/main/webapp),所以需要對該插件進行適當地配置。<warSourceDirectory>就是 Web工程的Web Root目錄,此處設置為;<webappDirectory>是制作war文件之前,相當于是一個被打開(exploded)的war文件 的根目錄(默認是target/artifactId-version)。
        該工程的腳本中,還使用了一個JBoss插件。該插件可以將制作好的war文件部署(實質上是拷貝)到指定的JBoss部署目錄中。< jbossHome>是JBoss的安裝根目錄,<serverName>指JBoss Server的名稱,<fileName>是被部署war文件的名稱。

    參考資源
    [1]Maven入門--概念與實例. http://www.tkk7.com/jiangshachina/archive/2006/09/01/67080.html
    [2]Maven + Continuum Weed. http://www.tkk7.com/jiangshachina/archive/2006/09/11/68944.aspx
    [3]Maven POM Reference. http://maven.apache.org/pom.html
    [3]db4o. http://www.db4objects.com
    本文實例下載地址--http://www.tkk7.com/files/jiangshachina/mvn-demo.rar

    null

    發表于 2007-3-19 12:38

    Maven入門--概念與實例

    1 關鍵名詞
        Project:任何您想build的事物,Maven都可以認為它們是工程。這些工程被定義為工程對象模型(POM,Poject Object Model)。一個工程可以依賴其它的工程;一個工程也可以由多個子工程構成。
        POM:POM(pom.xml)是Maven的核心文件,它是指示Maven如何工作的元數據文件,類似于Ant中的build.xml文件。POM文件位于每個工程的根目錄中。
        GroupId:groupId是一個工程的在全局中唯一的標識符,一般地,它就是工程名。groupId有利于使用一個完全的包名,將一個工程從其它有類似名稱的工程里區別出來。
        Artifact:artifact 是工程將要產生或需要使用的文件,它可以是jar文件,源文件,二進制文件,war文件,甚至是pom文件。每個artifact都由groupId和 artifactId組合的標識符唯一識別。需要被使用(依賴)的artifact都要放在倉庫(見Repository)中,否則Maven無法找到 (識別)它們。
        Dependency:為了能夠build或運行,一個典型的Java工程會依賴其它的包。在Maven中,這些被依賴的包就被稱為dependency。dependency一般是其它工程的artifact。
        Plug-in:Maven是由插件組織的,它的每一個功能都是由插件提供的。插件提供goal(類似于Ant中的target),并根據在POM中找到的元數據去完成工作。主要的Maven插件要是由Java寫成的,但它也支持用Beanshell或Ant腳本寫成的插件。
        Repository:倉庫用于存放artifact,它可以是本地倉庫,也可以是遠程倉庫。Maven有一個默認的遠程倉庫--central,可以從http://www.ibiblio.org/maven2/下載其中的artifact。在Windows平臺上,本地倉庫的默認地址是User_Home\.m2\repository
        Snapshot:工程中可以(也應該)有一個特殊版本,它的版本號包括SNAPSHOT字樣。該版本可以告訴Maven,該工程正處于開發階段,會經常更新(但還未發布)。當其它工程使用此類型版本的artifact時,Maven會在倉庫中尋找該artifact的最新版本,并自動下載、使用該最新版。
    2 Maven Build Life Cycle
        軟件項目一般都有相似的開發過程:準備,編譯,測試,打包和部署,Maven將上述過程稱為Build Life Cycle。在Maven中,這些生命周期由一系列的短語組成,每個短語對應著一個(或多個)操作;或對應著一個(或多個)goal(類似于Ant中的 target)。
        如編譯源文件的命令mvn compile中的compile是一個生命周期短語。同時該命令也可以等價于mvn compiler:compile,其中的compiler是一個插件,它提供了compile(此compile與mvn compile中的compile意義不同)goal;compiler還可提供另一個goal--testCompile,該goal用于編譯junit測試類。
        在執行某一個生命周期時,Maven會首先執行該生命周期之前的其它周期。如要執行compile,那么將首先執行validate,generate- source,process-source和generate-resources,最后再執行compile本身。關于Maven中默認的生命周期短語,請見參考資源[6]中的附錄B.3
    3 標準目錄布局
        Maven為工程中的源文件,資源文件,配置文件,生成的輸出和文檔都制定了一個標準的目錄結構。Maven鼓勵使用標準目錄布局,這樣就不需要進行額外 的配置,而且有助于各個不同工程之間的聯接。當然,Maven也允許定制個性的目錄布局,這就需要進行更多的配置。關于Maven的標準目錄布局,請見參考資源[6]中的附錄B.1
    4 Maven的優點
        [1]build邏輯可以被重用。在Ant中可能需要多次重復地寫相同的語句,但由于POM的繼承性,可以復用其它的POM文件中的語句。這樣既可以寫出清晰的build語句,又可以構造出層次關系良好的build工程。
        [2]不必關注build工作的實現細節。我們只需要使用一些build生命周期短語就可以達到我們的目標,而不必管Maven是如何做到這些的。如,只需要告訴Maven要安裝(install),那么它自然就會驗證,編譯,打包,及安裝。
        [3]Maven會自動加載工程依賴的artifact所依賴的其它artifact(Transitive Dependency),而不用顯示的將這些artifact全部寫到dependency中。
        [4]如果完全使用Maven的標準目錄布局,那么可以極大地減少配置細節。
    5 實例
    5.1 構想
        由于只是闡述Maven的基本使用方法,所以本文將要設計的實例,只是一個簡單的Maven demo。該實例包含兩個工程:普通應用程序工程(app)和Web應用工程(webapp)。app工程提供一個簡單的Java類;webapp工程只 包含一個Servlet,并將使用app中的Java類。
        該Demo的目標是能夠正確地將webapp制成war包,以供部署時使用。要能夠正確制作war,自然首先就必須要能夠正確的編譯源代碼,且要將App模塊制成jar包。本文創建的工程所在的目錄是D:\maven\demo
    5.2 App工程
        可以使用Maven的archetype插件來創建新工程,命令如下:
        D:\maven\demo>mvn archetype:create -DgroupId=ce.demo.mvn -DartifactId=app
    該工程的groupId是ce.demo.mvn,那么該工程的源文件將放在Java包ce.demo.mvn中。artifactId是app,那么該工程根目錄的名稱將為app。
        當第一次執行該命令時,Maven會從central倉庫中下載一些文件。這些文件包含插件archetype,以及它所依賴的其它包。該命令執行完畢后,在目錄D:\maven\demo下會出現如下目錄布局:
    app
    |-- pom.xml
    `-- src
        |-- main
        |   `-- java
        |       `-- ce
        |           `-- demo
        |               `-- mvn
        |                   `-- App.java
        `-- test
            `-- java
                `-- ce
                    `-- demo
                        `-- mvn
                            `-- AppTest.java

    因本文暫時不涉及JUnit測試,故請將目錄app\src\test目錄刪除(不刪除也沒關系 ^_^)。然后再修改App.java文件,其完全內容如下:
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">package ce.demo.mvn;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    public class App screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">{
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    public String getStr(String str) screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">{
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    return str;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">    }

    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">}

    其實,如果我們能夠清楚地知道Maven的標準目錄布局,就可以不使用archetype插件來創建工程原型;如果我們要定制個性的目錄布局,那么就更沒有必要使用archetype插件了。
    5.3 WebApp工程
        我們仍然如創建app工程一樣使用archetype插件來創建webapp工程,命令如下:
       
    D:\maven\demo>mvn archetype:create -DgroupId=ce.demo.mvn -DartifactId=webapp -DarchetypeArtifactId=maven-archetype-webapp
        第一次運行此命令時,也會從central倉庫中下載一些與Web應用相關的artifact(如javax.servlet)。此命令與創建app的命 令的不同之處是,多設置了一個屬性archetypeArtifacttId,該屬性的值為maven-archetype-webapp。即告訴 Maven,將要創建的工程是一個Web應用工程。創建app工程時沒有使用該屬性值,是由于archetype默認創建的是應用程序工程。同樣的,執行 完該命令之后,會出現如下標準目錄布局:
    webapp
    |-- pom.xml
    `-- src
        `-- main
            `-- webapp
                
    [size=+0]|
    -- index.jsp
                |-- WEB-INF
                    `-- web.xml

        根據5.1節的構想,webapp工程將只包含一個Servlet,所以我們不需要index.jsp文件,請將其刪除。此時大家可以發現,目前的目錄布 局中并沒有放Servlet,即Java源文件的地方。根據參考資源[6]中的附錄B.1,以及app工程中Java源文件的布局,可以知道 Servlet(它仍然是一個Java類文件)仍然是放在webapp\src\main\java目錄中,請新建該目錄。此處的Servlet是一個簡單HelloServlet,其完整代碼如下:
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">package hello;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import java.io.IOException;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import java.io.PrintWriter;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import javax.servlet.ServletException;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import javax.servlet.http.HttpServlet;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import javax.servlet.http.HttpServletRequest;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import javax.servlet.http.HttpServletResponse;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    import ce.demo.mvn.App;  // 引用app工程中的App類
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">

    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    public class HelloServlet extends HttpServlet screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">{
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    private static final long serialVersionUID = -3696470690560528247L;
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">            
    throws ServletException, IOException screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">{
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        App app
    = new App();
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        String str
    = app.getStr("CE Maven Demo");
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        PrintWriter out
    = response.getWriter();
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        out.print(
    "<html><body>");
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        out.print(
    "<h1>" + str);
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        out.print(
    "</body></html>");
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">    }

    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">}

    5.4 POM文件
        大家可以發現,在前面新建工程時,我們并沒有提到各個工程中的pom.xml文件。現在將要討論這個問題。我們先看看app工程中的POM文件,其完整內容如下:
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0"><project>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <modelVersion>4.0.0</modelVersion>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <groupId>ce.demo.mvn</groupId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <artifactId>app</artifactId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <packaging>jar</packaging>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <version>1.0</version>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <name>CE Maven Demo -- App</name>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    </project>

        大家可以發現此我帖出來的內容與實際由archetype插件生成的POM文件的內容有些不同,但基本上是一致的。只是為了使文件中的語句更清晰,此處刪 除了一些冗余的內容,并修改了該工程的version和name的值,以與此例子的背景來符合。在目前情況下modelVersion值將被固定為 4.0.0,這也是Maven2唯一能夠識別的model版本。groupId,artifactId的值與創建工程時使用的命令中的相關屬性值是一致 的。packaging的值由工程的類型決定,如應用程序工程的packaging值為jar,Web應用工程的packaging值為war。上述情況 也可以從webapp的POM文件中看出,下面將看看這個pom的完整內容。
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0"><project>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <modelVersion>4.0.0</modelVersion>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <groupId>ce.demo.mvn</groupId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <artifactId>webapp</artifactId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <packaging>war</packaging>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <version>1.0</version>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <name>CE Maven Demo -- WebApp</name>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    <dependencies>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">      
    <dependency>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">         
    <groupId>ce.demo.mvn</groupId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">         
    <artifactId>app</artifactId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">         
    <version>1.0</version>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">      
    </dependency>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <dependency>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    <groupId>javax.servlet</groupId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    <artifactId>servlet-api</artifactId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    <version>2.4</version>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    <scope>provided</scope>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    </dependency>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">  
    </dependencies>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    </project>

        比較app與webapp中的POM,除前面已經提過的packaging的差別外,我們還可以發現webapp中的POM多了dependencies 項。由于webapp需要用到app工程中的類(見HelloServlet源代碼),它還需要javax.servlet包(因為該包并不默認存在于 jsdk中)。故,我們必須要將它們聲明到依賴關系中。
    5.5 執行
        上述兩個工程創建完畢后,就需要執行一些命令來看看會有什么結果出現。我們首先進入app目錄,并執行命令mvn compile,然后會在該目錄下發現新生成的目錄target\classes,即編譯后的class文件(包括它的包目錄)就放在了這里。再執行命令mvn package,在目錄target中就會生成app-1.0.jar文件。該文件的全名由如下形式確定:artifactId-version.packaging。根據第2章的敘述可以知道,執行命令mvn package時,將首先將產生執行命令mvn compile之后的結果,故如果要打包,那么只需要執行mvn package即可。
        在app工程中執行完之后,就需要進入webapp工程了。進入webapp目錄,此次將只執行mvn package命令(隱示地執行了compile過程)。此次命令的執行并不成功,會出現如下問題:
    D:\maven\demo\webapp>mvn package
    ……
    Downloading: http://repo1.maven.org/maven2/ce/demo/mvn/app/
    1.0/app-1.0.pom
    [INFO] ------------------------------------------------------------------------
    [ERROR] BUILD ERROR
    [INFO] ------------------------------------------------------------------------
    [INFO] Error building POM (may not be this project's POM).
    Project ID: ce.demo.mvn:app
    Reason: Error getting POM for 'ce.demo.mvn:app' from the repository: Error transferring file
      ce.demo.mvn:app:pom:
    1.0
    from the specified remote repositories:
      central (http://repo1.maven.org/maven2)
    ……

        由粗體內容可知,Maven正試圖從central倉庫下載app工程的artifact,但central倉庫肯定不會有這個artifact,其結果 只能是執行失敗!由第1章artifact名詞的解釋可知,被依賴的artifact必須存在于倉庫(遠程或本地)中,但目前webapp所依賴的app 必不存在于倉庫中,所以執行只能失敗。
        解決這個問題有兩種方法:[1]將app-1.0.jar安裝到倉庫中,使它成為一個artifact;[2]構建一個更高層次的工程,使app和webapp成為這個工程的子工程,然后從這個更高層次工程中執行命令。
        第一種方法比較簡單(
    見),此處將詳細討論第2種方法(見5.6節)。
    5.6 更高層次工程
        我們可以將app和webapp的上一級目錄demo作為這兩個工程的 一個
    更高層次工程,即使用app和webapp成為這個工程的子工程。為了使demo目錄成為一個demo工程,只需要在這個目錄下添加一個pom.xml文件,該文件內容如下:
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0"><project>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <modelVersion>4.0.0</modelVersion>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <groupId>ce.demo</groupId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <artifactId>mvn-demo</artifactId>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <packaging>pom</packaging>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <version>1.0</version>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <name>CE Maven Demo</name>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    <modules>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    <module>app</module>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">        
    <module>webapp</module>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">   
    </modules>
    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" onmousewheel="return imgzoom(this);" alt="" border="0">
    </project>

        與app和webapp中的POM相比,demo的POM使用了modules項,modules用于聲明本工程的子工程,module中的值對應于子工程的artifact名。而且該POM的packaging類型必須為pom。
        有了demo工程后,我們只需要在demo目錄下執行相關命令就可以了。通過如下命令即可驗證:
        [1]mvn clean – 消除工程(包括所有子工程)中產生的所有輸出。這本文的實例中,實際上是刪除target目錄。由于之前的操作只有app工程產生了target目錄,而webapp并沒有,所以將只會刪除app工程中的target目錄。
        [2]mvn package – 將工程制作成相應的包,app工程是作成jar包(app-1.0.jar),webapp工程是作成war包(webapp-1.0.war)。打開 webapp-1.0.war包,可以發現app-1.0.jar被放到了WEB-INF的lib目錄中。
    6 小結
        通過以上的敘述與實例,應該可以對Maven有一個粗略的認識了。使用Maven關鍵是要弄清楚如何寫pom.xml文件,就如同使用Ant要會寫 build.xml文件一樣。在POM中可以直接寫入Ant的task腳本,也可以調用Ant的build.xml文件(推薦),所以Maven也可以完 成Ant的絕大多數工作(但不必安裝Ant)。注意:使用Maven就不要再過多的使用Ant腳本
        利用好Maven的繼承特性及子工程的關系,可以很好地簡化POM文件,并能夠構建層次結構良好的工程,有利于工程的維護。
    7 參考資源
    [1]Maven官方網站. http://maven.apache.org
    [2]Maven POM文件參考結構. http://maven.apache.org/ref/current/maven-model/maven.html
    [3]Super POM. http://maven.apache.org/guides/introduction/introduction-to-the-pom.html
    [4]Maven主要插件的列表. http://maven.apache.org/plugins
    [5]Maven基本使用指南. http://maven.apache.org/guides/index.html
    [6]Better Build with Maven. http://www.mergere.com/m2book_download.jsp -- 強烈推薦
    [7]介紹Maven2. http://www.javaworld.com/javaworld/jw-12-2005 /jw-1205-maven_p.html
    [8]揭秘Maven2 POM. http://www.javaworld.com/javaworld/jw-05-2006/jw-0529-maven.html
    [9]Maven讓事情變得簡單. http://www-128.ibm.com/developerworks/cn/java/j-maven
    [10]Maven文檔集. http://docs.codehaus.org/display/MAVENUSER/Home
    [11]有效利用Maven2的站點生成功能. http://www.matrix.org.cn/resource/article/44/44491_Maven2.html
    http://www.tkk7.com/jiangshachina/admin/EditPosts.aspx中的第一個主題
    posted on 2008-01-10 23:10 禮物 閱讀(837) 評論(0)  編輯  收藏 所屬分類: maven2
    主站蜘蛛池模板: 久久综合AV免费观看| 久久www免费人成看国产片| 亚洲午夜电影在线观看| 亚洲熟妇无码久久精品| 亚洲天堂电影在线观看| 亚洲a级片在线观看| 亚洲成年网站在线观看| 亚洲老熟女五十路老熟女bbw| 亚洲日韩中文字幕无码一区| 亚洲国产精品99久久久久久| 18禁亚洲深夜福利人口| 边摸边脱吃奶边高潮视频免费| 精品一区二区三区无码免费直播| 美女视频黄.免费网址| jizz日本免费| 国产免费一区二区视频| 亚洲黄色免费网站| 69成人免费视频无码专区| 性做久久久久免费观看| 亚洲国产精品一区二区三区久久 | 亚洲日本国产综合高清| 亚洲国产日韩综合久久精品| 亚洲人成网站999久久久综合| 国产精品国产亚洲区艳妇糸列短篇 | 免费一级毛片正在播放| 亚洲精品和日本精品| 国产成人综合亚洲AV第一页| 亚洲国产精品久久久久| 亚洲国产91在线| 美女扒开屁股让男人桶爽免费| 中文字幕无线码免费人妻| 最近中文字幕完整版免费高清| 成人性生活免费视频| 亚洲高清国产拍精品青青草原| 亚洲成Av人片乱码色午夜| 亚洲一区在线视频| 日本激情猛烈在线看免费观看| 在线观看人成视频免费无遮挡| 在线观看H网址免费入口| mm1313亚洲国产精品美女| 久久夜色精品国产亚洲AV动态图|