maven2学习

建议您先按照本文试试火,然后再看看maven的站点文档会比较节约时间,
因为开始时我看了一堆文档仍然不了解它到底在干啥,做了几个试验才明白,
由于maven鼓励各项目共用同一个jar资料库,所以象ant般在每个项目的lib中存放jar将
很少发生,而且并不需要你自己下载所有的依赖jar,只用告所它:名称-版本就行了,它会在
一些集中放置jar的网站自动下载,稍慢了些,不过,以后你就明白这样的好处了。
1.下载:
http://maven.huangdong.com/start/download.html
我们应挑选其中的中文版下载:http://maven.huangdong.com/dist/
目前最后版本:MavenCN 1.0 RC2
2.安装:
解压到硬盘,我解压到:D:/frameworks/maven-1.0-rc2
设置MAVEN_HOME环境变量为解压目录:  MAVEN_HOME=D:/frameworks/maven-1.0-rc2
(又设环境变量!为何不能自己把自己的目录设为MAVEN_HOME呢? :-<  
可能因为我们还要经常运用MAVEN_HOME/bin/maven.bat   )
运行maven.bat来看看maven是否可用:
在命令行执行maven.bat出现下面的输出则说明你的maven可以运行了:
-------------------------------------------------------------
D:/frameworks/maven-1.0-rc2/bin>meven
__  __
|  //  |__ _Apache__ ___    __ ___
| |//| / _` / V / -_) &#39; / /  _| &#39; /  ~ intelligent projects ~
|_|  |_/__,_|/_//___|_||_|/___|_||_|  v. 1.0-rc2
BUILD SUCCESSFUL
-------------------------------------------------------------
3.  ok现在就跑个小项目试试火力
此项目针只对几个java文件(web开发稍候再试...),来看看它的编译和打包jar功能和ant有何不同.
先建立一个新的目录   d:/test/maven
maven鼓励在path中设置maven的解压路径,这样就可以随时执行maven.bat了,可我觉得尽量少的在机器上
设置可能更好些(刚才设了个maven_home现在还耿耿于怀:-),所以我会为每个项目建立一个maven.bat:
d:/test/maven/maven.bat
-----------------------------------------
%MAVEN_HOME%/bin/maven  %1 %2 %3 %4 %5
-----------------------------------------

ok,现在我们的目录中只有一个便利的bat而已,用maven生成模板为我们制造一个初始环境目录结构:
D:/test/maven>maven genapp
按照提示随便输入一些信息(模版程序的参数),或者简单的全部回车
D:/test/maven>maven genapp
屏幕输出:
----------------------------------------------------------------------
__  __
|  //  |__ _Apache__ ___    __ ___
| |//| / _` / V / -_) &#39; / /  _| &#39; /  ~ intelligent projects ~
|_|  |_/__,_|/_//___|_||_|/___|_||_|  v. 1.0-rc2
Enter a project template to use: [default]
Please specify an id for your application:  [app]
chen56
Please specify a name for your application:   Example Application
chen56
Please specify the package for your application:  [example.web]
chen56
----------------------------------------------------------------------
哇,发现目录中多了几个文件和文件夹,这是maven的genapp插件所提供的模版结构。
我们的meven目录:
-----------------------------------------------
|-- project.properties
|-- project.xml
`-- src
    |-- conf
    |   `-- app.properties
    |-- java
    |   `-- chen56
    |       `-- App.java
    `-- test
        `-- chen56
            |-- AppTest.java
            |-- AbstractTestCase.java
            `-- NaughtyTest.java
-----------------------------------------------
先不管它生成了啥东东,用屁股想想也知道大概是一些个配置文件
再输入:
D:/test/maven>maven java:compile
看看目录中多了个target目录,这也是maven默认的编译目录,里边已经把文件们都编译过了。
再输入:
D:/test/maven>maven jar
发现屏幕输出显示编译、测试、打包jar...,看看target目录,多了个chen56-1.0.jar文件,我们的成果已经被
打包了,哦哦,这样就行了吗?当然不行,在接下来的更复杂的web例子中我们先来讲讲刚才都作了什末。

/*
构造本地资源库(repository),这也是以后放置所有第三方类库的地方,比如junit放在:
repository/junit/jars/junit-3.8.1.jar
maven默认为%HOME%/.maven目录下:在我的WIN2000也就是:
C:/Documents and Settings/chen56/.maven/           本地资源库
C:/Documents and Settings/chen56/.maven/plugins/   maven插件
C:/Documents and Settings/chen56/.repository/      第3方类库
要完成此构造要运行maven-1.0-rc2/bin/install_repo.bat命令,要运行这个bat,就要设置
MAVEN_HOME 环境变量,我简单的建立另一个批处理文件 install.bat:
|----------------------------------------------
|  set MAVEN_HOME=../
|  install_repo %USERPROFILE%/.maven/repository
|-----------------------------------------------
运行install.bat,则会把maven自带的一些类库copy到repository目录中,并作一些它的初始化,天晓得它还干了啥。
*/

 

 

Maven入门--概念与实例

    最近由于工作原因在研究、应用Maven,有了一些体会就写成了此文。本文虽然是Maven2的入门文章,但并不涉及Maven的历史、下载与安装,这些内容可以到Maven的官方网站上了解。本文主要是关注Maven中的重要概念,并以一个实例来阐述使用Maven的基本方法。文末有例子代码下载的链接。(2006.10.29最后更新)
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,而不用显示的将这些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和webapp成为这个工程的子工程。为了使demo目录成为一个demo工程,只需要在这个目录下添加一个pom.xml文件,该文件内容如下:

app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- ce
    |           `-- demo
    |               `-- mvn
    |                   `-- App.java
    `-- test
        `-- java
            `-- ce
                `-- demo
                    `-- mvn
                        `-- AppTest.java

因本文暂时不涉及JUnit测试,故请将目录app/src/test目录删除(不删除也没关系 ^_^)。然后再修改App.java文件,其完全内容如下:
其实,如果我们能够清楚地知道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默认创建的是应用程序工程。同样的,执行完该命令之后,会出现如下标准目录布局:

package  ce.demo.mvn;
public   class  App  {
    
public String getStr(String str) {
        
return str;
    }

}

 

webapp
|-- pom.xml
`-- src
    `-- main
        `-- webapp
           
| -- 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,其完整代码如下:

package  hello;

import  java.io.IOException;
import  java.io.PrintWriter;
import  javax.servlet.ServletException;
import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;

import  ce.demo.mvn.App;   //  引用app工程中的App类

public   class  HelloServlet  extends  HttpServlet  {
    
private static final long serialVersionUID = -3696470690560528247L;
    
public void doGet(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, IOException {
        App app 
= new App();
        String str 
= app.getStr("CE Maven Demo");
        PrintWriter out 
= response.getWriter();
        out.print(
"<html><body>");
        out.print(
"<h1>" + str);
        out.print(
"</body></html>");
    }

}

5.4 POM文件
    大家可以发现,在前面新建工程时,我们并没有提到各个工程中的pom.xml文件。现在将要讨论这个问题。我们先看看app工程中的POM文件,其完整内容如下:

< project >
  
< modelVersion > 4.0.0 </ modelVersion >
  
< groupId > ce.demo.mvn </ groupId >
  
< artifactId > app </ artifactId >
  
< packaging > jar </ packaging >
  
< version > 1.0 </ version >
  
< name > CE Maven Demo -- App </ name >
</ project >

    大家可以发现此我帖出来的内容与实际由archetype插件生成的POM文件的内容有些不同,但基本上是一致的。只是为了使文件中的语句更清晰,此处删除了一些冗余的内容,并修改了该工程的version和name的值,以与此例子的背景来符合。在目前情况下modelVersion值将被固定为4.0.0,这也是Maven2唯一能够识别的model版本。groupId,artifactId的值与创建工程时使用的命令中的相关属性值是一致的。packaging的值由工程的类型决定,如应用程序工程的packaging值为jar,Web应用工程的packaging值为war。上述情况也可以从webapp的POM文件中看出,下面将看看这个pom的完整内容。

< project >
  
< modelVersion > 4.0.0 </ modelVersion >
  
< groupId > ce.demo.mvn </ groupId >
  
< artifactId > webapp </ artifactId >
  
< packaging > war </ packaging >
  
< version > 1.0 </ version >
  
< name > CE Maven Demo -- WebApp </ name >
  
  
< dependencies >
      
< dependency >
          
< groupId > ce.demo.mvn </ groupId >
          
< artifactId > app </ artifactId >
          
< version > 1.0 </ version >
      
</ dependency >
    
< dependency >
        
< groupId > javax.servlet </ groupId >
        
< artifactId > servlet-api </ artifactId >
        
< version > 2.4 </ version >
        
< scope > provided </ scope >
    
</ dependency >  
  
</ dependencies >
</ 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过程)。此次命令的执行并不成功,会出现如下问题:
    由粗体内容可知,Maven正试图从central仓库下载app工程的artifact,但central仓库肯定不会有这个artifact,其结果只能是执行失败!由第1章artifact名词的解释可知,被依赖的artifact必须存在于仓库(远程或本地)中,但目前webapp所依赖的app必不存在于仓库中,所以执行只能失败。
    解决这个问题有两种方法:[1]将app-1.0.jar安装到仓库中,使它成为一个artifact;[2]构建一个更高层次的工程,使app和webapp成为这个工程的子工程,然后从这个更高层次工程中执行命令。
    第一种方法比较简单(http://www.blogjava.net/jiangshachina/admin/EditPosts.aspx中的第一个主题),此处将详细讨论第2种方法(见5.6节)。
5.6 更高层次工程
    我们可以将app和webapp的上一级目录demo作为这两个工程的

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)
……

 

< project >
    
< modelVersion > 4.0.0 </ modelVersion >
    
< groupId > ce.demo </ groupId >
    
< artifactId > mvn-demo </ artifactId >
    
< packaging > pom </ packaging >
    
< version > 1.0 </ version >
    
< name > CE Maven Demo </ name >
    
    
< modules >
        
< module > app </ module >
        
< module > webapp </ module >
    
</ modules >
</ 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.blogjava.net/files/jiangshachina/maven.rar

posted on 2006-09-01 13:43 Sha Jiang 阅读(444) 评论(2)   编辑  收藏 引用 收藏至365Key 所属分类: Maven


FeedBack:

#  re: Maven入门--概念与实例
2006-11-26 14:52 | cmd
辛苦了,收益非浅,如果结合eclipse 生成工程并结合svn说明一下开发人员和管理人员如何使用mvn,就更有助于实际工作了,期待!    回复
  
#  re: Maven入门--概念与实例
2006-11-27 09:01 | Sha Jiang
生成Eclipse工程:mvn eclipse:eclipse

与SCM(CVS,SVN...)的结合也比较容易,一般只需要设置scm这个元素就可以了。请参见:
http://maven.apache.org/ref/current/maven-model/maven.html#class_scm
然后再使用maven-scm-plugin
http://maven.apache.org/scm/plugins/
就可以做checkout等等工作了。

最近在写一篇关于Maven的较复杂应用实例的文章,文中会尽量多使用一些插件及其设置,敬请关注 ^_^  
Maven入门--较复杂的实例
本文将使用一个较复杂的实例,讲述如何定制目录布局(即不使用Maven标准目录布局),以及讲述一些关键插件的使用(配置)。为了方便其它朋友能够方便地使用该实例,后台数据库使用开源的面向对象数据库--db4o,该数据库无需安装,已包含在与本文配套的实例中,文末附有该实例的下载链接(暂时还没有提供)。(2006.12.12最后更新)

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文件如下所示:
< 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 > 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 >
        
</ plugins >
    
</ build >
</ project >
    预定义工程的依赖关系,就是把会被子工程依赖的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, xml-apis xalan 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工程是一个普通application工程,它主要负责对数据库操作,如连接数据库、读取数据库的处理。该工程的POM文件完整内容如下所示:
< 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 > mvn.demo </ groupId >
        
< artifactId > demo </ artifactId >
        
< version > 1.0-SNAPSHOT </ version >
    
</ parent >

    
< modelVersion > 4.0.0 </ modelVersion >
    
< groupId > mvn.demo </ groupId >
    
< artifactId > demo-app </ artifactId >
    
< packaging > jar </ packaging >
    
< name > Maven Demo Application Project </ name >

    
< dependencies >
        
< dependency >
            
< groupId > com.db4o </ groupId >
            
< artifactId > db4o-java5 </ artifactId >
        
</ dependency >
    
</ dependencies >

    
< 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标准目录结构,但在第2节中却没的提到与目录结构相关的任何设置。现在我就要描述这一部分的设置。
Maven标准目录是由Super POM(所有POM文件的父POM)定义的(请见参考资源3,主题The Super POM),要使用定制的目录结构,就是要用新的值去“覆盖”原来的值。其实demo-app工程的POM文件中的多数语句就是用来定制目录结构的。
    <finalName>是工程输出的“产品”的名称,默认为artifaceId-version.packaging。必须注意的是,该设置并不会影响install或deploy到仓库中的artifact的名称,这个名称仍然会是aritfaceId-version.packaging的形式。
    <sourceDirectory>是工程Java源代码的目录(即Eclipse工程中的source folder)。默认为src/main/java,此处设置为src/java(这些路径都是相对于pom.xml文件的相对路径)。
    <outputDirectory>是工程Java源代码被编码后的class文件的存放目录(即Eclipse工程中的classes folder)。默认为target/classes,此处设置相同的值。
    <resources><resource>定义了Java源代码所使用的资源文件的存放目录。默认为src/main/resources,此处设置为src/java,即与Java源文件是同一个目录。这样就需要考虑一个问题:Maven会将所有的源文件当作资源文件拷贝到jar文件中。所以需要在<excludes><exclude>中排除所有.java文件(详见该工程的POM脚本)。
    <testSourceDirectory>是工程的Unit测试源代码的存放目录,默认为src/test/java,此处设置为相同的值。
    <testOutputDirectory>是工程的Unit测试源代码编码后的class文件后存放目录。默认为target/test-classes,此处设置为相同的值。

    <testResources><testResource>定义了Unit测试代码要使用的资源文件的存放目录。默认为src/test/resources,此处设置为src/test/java,
但排除了所有的.java文件(理由请见 <resources><resource> 中的相关说明)。
    通过上述设置,就已经拥有了一个定制的工程目录结构。

4 demo-web工程

demo-web工程是一个Web应用工程,它将使用demo-app工程中数据库应用程序去访问db4o数据库文件,将其中的数据查询出来并显示到页面中。该工程的POM完整内容如下所示:
< 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 > mvn.demo </ groupId >
        
< artifactId > demo </ artifactId >
        
< version > 1.0-SNAPSHOT </ version >
    
</ parent >

    
< modelVersion > 4.0.0 </ modelVersion >
    
< groupId > mvn.demo </ groupId >
    
< artifactId > demo-web </ artifactId >
    
< packaging > war </ packaging >
    
< name > Maven Demo Web Application Project </ name >

    
< dependencies >
        
< dependency >
            
< groupId > mvn.demo </ groupId >
            
< artifactId > demo-app </ artifactId >
           
<version>1.0-SNAPSHOT</version>
        </ dependency >
        
< dependency >
            
< groupId > javax.servlet </ groupId >
            
< artifactId > servlet-api </ artifactId >
        
</ dependency >
        
< dependency >
            
< groupId > commons-configuration </ groupId >
            
< artifactId > commons-configuration </ artifactId >
        
</ dependency >
    
</ dependencies >

    
< build >
        
< finalName > demo </ 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 >

        
< 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 >
    可以发现上述POM脚本与demo-app工程POM脚本的内容/形式大部分是相同的。所以在这里主要是讲述它们的不同之处--对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.blogjava.net/jiangshachina/archive/2006/09/01/67080.html
[2]Maven + Continuum Weed. http://www.blogjava.net/jiangshachina/archive/2006/09/11/68944.aspx
[3]Maven POM Reference. http://maven.apache.org/pom.html
[3]db4o. http://www.db4objects.com

 

    根据实际情况,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值