让我们开始使用Maven。在本章结束时,你应该能够从头建立一个Maven的项目,使用Maven进行相关管理,创建基于某些感兴趣报告的简单的web站点。
安装Maven
开始本书以前,你有一些必备的安装工作。本书中的例子用Java1.4.2编写,Maven能够兼容Java1.4.2和Java1.5.0。本书中所写Maven的最新版本是在编写本书时发布的—Maven 1.0.2。除JDK和Maven1.0.2之外,你还需要连接到Internet,Maven将通过公网站点下载相关其需要的。那么,前进,安装Maven吧。
我该如何做?
从Apache Software Foundation(ASF)下载Maven。进入从左侧的导航菜单中的Getting Maven菜单选择下载。它将带你进入一个让你选择Windows 安装包、zip文件、tar'd.bzip文件或者tar'd.gzip文件。下载适合你平台的分类。
我该如何做?
从Apache Software Foundation(ASF)下载Maven。进入从左侧的导航菜单中的Getting Maven菜单选择下载。它将带你进入一个让你选择Windows 安装包、zip文件、tar'd.bzip文件或者tar'd.gzip文件。下载适合你平台的分类。
提示
某些Developer's Notebook中涉及的插件未与Maven1.0.2绑定。请参考第6章并且附录A有安装Maven所需插件的全部列表以及详细说明。
在Microsoft Windows平台,下载Windows安装包(maven-1.0.2.exe),跟随自动安装过程中的提示。在使用Maven Windows 安装器进行安装后,你应该定义一个用户环境变量,MAVEN_HOME,指向你本地的Maven安装。你此时需要进入控制面版→系统→高级选择环境变量按钮,添加%MAVEN_HOME%\bin到你的PATH环境变量。进入命令提示行运行cmd.exe,如果Maven安装成功,你将能够看到命令行有下面的输出:
C:\dev\mavenbook\code>maven -v
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
|_| |_\__,_|\_/\___|_||_| v. 1.0.2
如果你愿意安装Maven到一个除了C:\Program Files\Apache Software Foundation\Maven 1.0.2的目录,你也可以下载Maven1.0.2.zip文件,解压缩到任何目录。设置MAVEN_HOME指 向到Maven解压缩的目录,并且添加%MAVEN_HOME%\Bin到你的PATH环境变量。
在Unix平台,下载tar'd.zip文件(Maven-1.0.2.tar.gz)并接压缩tar xvzf maven-1.0.2.tar.gz到你选择的目录。本试验假设你解压Maven到/usr/local/maven-1.0.2目录下。你此时需要设置两个环境变量,MAVEN_HOME和PATH。下面的命令为这两个变量设置适当的值:
[tobrien@mavenbook tobrien]$ export MAVEN_HOME=/usr/local/maven-1.0.2
[tobrien@mavenbook tobrien]$ export PATH=${PATH}:${MAVEN_HOME}/bin
如果Maven被成功安装到你的机器,你能够看到与Windows系统同样的输出。恭喜!你已经成安装了Maven。
提示
有些人喜欢保存本地应用程序在Unix下的/opt目录或
Windows下的c:\apps。你可以根据个人喜好安装Maven。
刚刚发生了什么?
你刚刚安装了Maven1.0.2并且配置了一些环境变量。是的!一旦你对MAVEN_HOME进行了有效的设置或是maven.bat或maven.sh已经存在,你已经能够完成Developer's Notebook本次的实验。
关于......Maven 2?
是时机提及Maven 2(有时也被称为“m2”)。Maven 2完成了对Maven 1的重写。重写的首要目的是要提供了强大的Jave构建和包含API的项目,允许Maven被植入任何地方,尤其是高级别的产品如IDEs、质量工具、报告工具等这些。Maven 2构建生命周期的概念正式话,其比Maven更易扩展。
Maven 1和Maven 2有许多共同点,但它们还有几个主要的不同之处。在书中的各个部分我们尽可能提示你所希望了解的那些不同之处。更多关于Maven 2的信息,请转到下载Maven 2的体验版本,并加入Maven用户或开发者邮件列表。如果你听过Continuous Integration,你可能也想看一看命名为Continuum的Maven子项目,地址在。
开始一个新的项目
创建新项目的争论一部分在于有很大部分的工作努力被用到在“发展基础设施”上—自动构建、单元测试、文档、项目报告等。使用Maven你可以加速这个过程,生成项目的框架使其作为新应用的种子。
我该如何做?
Maven拥有一个应用程序生成插件(Genapp)你能通过其创建一个新项目。首先创建一个空的目录c:\dev\mavenbook\code\genapp\test-application这将成为应用程序生成后的处所。通过执行genapp这个目标来运行Genapp插件,选择默认的模版并且提供一些你的新项目的相关信息。
C:\dev\mavenbook\code\genapp\test-application>maven genapp
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
|_| |_\__,_|\_/\___|_||_| v. 1.0.2
Attempting to download commons-jelly-tags-interaction-20030211.143817.jar.4K downloadedEnter a project template to use: [default][Enter]Please specify an id for your application:
[app]test-applicationPlease specify a name for your application: [Example Application]Test ApplicationPlease specify the package for your application: [example.app]mdn.testappbuild:start:genapp:
[copy] Copying 1 file to C:\dev\mavenbook\code\genapp\test-application\src\java\mdn\testapp[copy] Copying 3 files to C:\dev\mavenbook\code\genapp\test-application\src\test\mdn\testapp[copy] Copying 1 file to C:\dev\mavenbook\code\genapp\test-application\[copy] Copying 2 files to C:\dev\mavenbook\code\genapp\test-application\BUILD SUCCESSFUL
本插件会要求用户一些输入,从这个输出内容你可以看到你使用了默认的(defalut)应用程序模板,并且你提供了新项目的应用程序ID、name,和包名。默认的(default)应用程序模板创建了一个单独的类,mdn.testapp.app,和一个静态main函数和两个JUnit测试。
Maven的应用程序生成插件生成了下面的目录和文件:
test-application/project.propertiesproject.xmlsrc/conf/app.propertiesjava/mdn/testapp/App.javatest/mdn/testapp/AbstractTestCase.javaAppTest.javaNaughtyTest.java
所有Maven项目有一个参考了项目对象模型(POM)的标准目录结构, (as described shortly)。如果你有一些现存的类你想添加到一个项目,添加它们到src/java,如果你有一些单元测试将它们添加到src/test。如果这些已有的类和单元测试依赖一些外部的苦,你将在随后的章节看到如何添加一个附属。xdos目录包含了格式为XDoc的项目文档。
提示
请注意Maven1.0.2装载的Genapp插件版本创建了非标准的布局。在Maven项目中src/java和src/test不再出现在固有的源代码和单元测试位置。取而代之的是你可以使用src/main/java和src/test/java.为了改变这些,修改你项目的xml文件,改变src/java的引用为src/main-/java,src/test的引用为src/test/java.更多的信息,请参见“Maven Conventions”,地址在.
project.xml是项目的描述符;它是一个内容为POM的XML文件。让我们看看这个project.xml的拷贝,其已经定义了这个项目:
3
test-application
Test Application
1.0
Your Organization
|jpg|...
2005
mdn.testapp
|gif|...
An example projec
现在,运行jar目标并且看看Maven的输出吧;它将包含下面如下这些。
Attempting to download spring-core-1.1.4.jar.266K downloadedAttempting to download spring-web-1.1.4.jar.111K downloaded
图1-1显示了jar目标触发的一系列事件:
1.Maven查看POM,依据project.xml的定义,看到在springframework组中的两个人造物的依赖关系。它将载你本地Maven的资源库中检查spring-core-1.1.4.jar和spring-web-1.1.4.jar。
2.当Maven找不到这些文件,它将到寻找JAR文件。这些JAR文件会被下载并放置于你本地Maven的资源库中。它们也被添加到你项目的classpath中。下次在你的项目查询这些文件时,Maven将在你本地的资源库中提供它们。
图1-1.Maven本地和远程资源库为test application项目提供的spring Jar
刚刚发生了什么?
Maven为你节省了相当的时间和不必要的麻烦。Maven到来之前,依赖关系常常被捆绑到一个项目的目录或者项目应该指向到添加正确的JAR到你的classpath。使用Maven管理依赖关系显然有着明显的优势;作为初学者,如果你的项目依赖30个外部的JAR文件,这就不需要在你的资源库中存储成兆的JAR文件。这意味着当你在项目的外部检查资源控制的时候更少的存储空间和更快的下载时间。另外,如果你有多个项目依赖相同的外部依赖,Maven仅需要下载一次依赖关系,并且每个项目引用一个单独的副本在你本地的资源库中。当依赖关系能够从Maven资源库远程下载的时候,没有强制的原因让你存储你项目的依赖关系的版本。
当Maven下载依赖关系,其在你本地的机器上从远程的Maven资源库拷贝一个文件到你本地的Maven资源库。Maven如何定位依赖关系的?它使用project.xml中dependency元素的信息,如图1-2所示。
图1-2.POM和Maven资源库的映射
指定的groupId告诉Maven查看特定的目录-springframework。指定type告诉Maven查找特定的子目录如jar和war(注意s是Maven附加到type元素上的);本例中,type是被忽略的,JAR类型是默认类型。当你指定了artifactId,你正告诉Maven哪个文件将从jar目录下载。顶级目录表现为组标示符,JAR文件名的第一部分表现为artifact标示符,文件名最后的部分,包括扩展名表现为version标示符。Maven使用下面的公式来决定一个来自于资源库中的依赖关系。[REPO_ROOT]参考你远程的资源库:
[REPO_ROOT]/
/s/-.
提示
Maven2.0的说明中,资源库可能开始于类似Java包的结构。作为springframework的替代,groupId被提议的结构为org.springframework.另外,每个版本将有一个分隔目录用以增加Maven资源库的效率。更多有关改变的提交建议,参见 MAVEN/Repository+Layout+-+Final.
一个本地的资源库来处理依赖关系。在Unix机器上,你的Maven资源库能在~/.maven/repository目录找到,在Windows机器上,你的Maven的资源库在你的%USERPROFILE%目录。如果你看一看本地Maven的资源库,你将会注意到它正包含一个springframework的目录。%USERPROFILE%\.maven\repository\springframework\jars目录包含spring-core依赖关系的两个:spring-core-1.1.4.jar文件和spring-core-1.1.4.jar.md5文件,其包含MD5文件用于验证sprint-core JAR文件的完整性。Maven 1当前并没有使用MD5来验证完成品的完整性,但在将来的版本可能会用其来验证完成品的完整性。
提示
在Windows机器上,%USERPROFILE%通常决定于C:\D-ocuments and Settings\vmassol这种目录。%USERPR-OFILE%被用在Unix的主目录。(%USERPROFILE% isused in the spirit of the abbreviation for a Unix home directory.)
关于......使用id元素?
如果你工作在现存的Maven项目,你可能有依赖关系使用id元素。下面的dependencies元素示范了使用单独id元素来附加Jakarta Commons Math的1.0版本:<;dependencies><;dependency><;id>commons-math<;/id><;version>1.0<;/version><;/dependency><;/dependencies>单独使用id元素工作仅在groupId和artifactId匹配时,如果你浏览Maven资源库,你将看到下面的目录结构:
/commons-math
/jars
commons-math-1.0.jar
commons-math-1.1.jar
使用id元素工作,单独的id标记已经不被赞成使用并在Maven 2中消失。当你看到别的Maven项目中使用dependencies的速记符号时,请尝试使用groupId和artifactId来标识你的依赖关系。
依赖快照
如果你开发的程序依赖的依赖关系经常改变,你可能想将依赖的每个依赖关系替代为最近构件的硬编码的版本。在一个项目依赖的依赖关系还处在beta的版本,或你正开发一系列项目依赖的Maven项目时时特别有用,这将在第3章论述。本实验,你将学习到如何依靠快照。
我该如何做?
在你的依赖关系块儿中指定一个明确的版本,使用SNAPSHOT关键字作为版本名称的一部分。每次你执行Maven目标时,Maven将从远程资源库中检查较新的依赖关系。如果远程资源库的版本较新Maven将下载其到本地资源库。例如:下面的依赖关系将一直下载spring的新版JAR文件。
springframework
spring
1.2-SNAPSHOT
刚刚发生了什么?
当你使用SNAPSHOT依赖关系,你正告诉Maven使用远程资源库的最新版本。在你使用多项目插件或者当你依赖的一个完成品尚处于开发阶段这将得心应手。在你工作的团队仅有较少的开发者组成时,最好也常这么做。你将使用SNAPSHOT依赖关系当你的项目依赖一个最近的开发或者非正式版本的特别组件。SNAPSHOT依赖关系应该在开发阶段被保留,并且,概括说,你不用改发布一个依赖于SNAPSHOT依赖关系的项目。
执行脱机构建
如果你需要在一个离线的情况下使用Maven,你可能需要知道如何确使Maven不检查最新的SNAPSHOT依赖关系。本实验将向你展示如何用Maven执行脱机构建。
我该如何做?
这个方法很简单:仅仅使用-o命令行选项。例如,如果你没有网络连接,但又想执行测试目标,运行Maven -o test。Maven将执行这个test目标而不检查依赖关系。如果你的项目没有依赖SNAPSHOT构建,你也可以断看你的环境来添加-o标志。如果你依赖SNAPSHOT构建,你将需要使用-o标志,Maven将在每次执行目标时尝试检查最新的SNAPSHOT。在这种情况下不使用-o标志本项目将不会构建成功。
关于...... 执行离线构建如果你不想下载任何完成品?
当然,这将不会工作。离线构建的工作,你必须已经有必需的依赖关系在你本地的资源库。项目最简单的获得Maven下载依赖
关系的方法是在每个Maven项目实例简单的运行“noop”目标,build:start。这个目标执行之前任何其它的目标并不执行任何动作。如果你运行build:start,Maven将从project.xml获得获取任何依赖关系。
使用Maven控制台
如果你再三的从命令行运行Maven,你可以通过Maven控制台来节省时间。Maven控制台提供一个“外壳”,在这你可以键入目标的名称来执行Maven。通过使用Maven可以避免每次载你想运行一个Maven目标时Java Virtual Machine(JVM)启动的等待。
我该如何做?
Maven Console是一个插件,你可以通过键入maven console在命令提示符。这将产生下面的输出:
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
|_| |_\__,_|\_/\___|_||_| v. 1.0.2The following commands are available:list - list all available goalshelp - this message - attain a goalquit - quits the consoletest-application 1.0 >
目前,你可以在命令行执行任何你能执行的目标。开始是一下;键入 java:compile。Maven将执行 java:compile目标并返回提示符其它的目标。在一个序列中运行两个目标,你可以在提示符处输入它们,通过“空格”-例如, clean test。众所周知作为“goal chaining”这是你想通过Maven获得指定一系列目标的方法。退出Maven Console,键入quit,查看有效目标列表,键入list。
刚刚发生了什么?
在Maven Console下Maven执行java:compile目标非常之快,不信么?当你使用Maven Console时你所执行的目标是在一个现成的JVM下。当你从命令行运行Maven时,你每次运行一个目标都不得不等待JVM的启动。如果你不确信其对性能的提升,自己试试看。在命令行下运行java:complie 10次,再在Maven Console下同样运行java:compile 10次。注意时间的差别,你将发现JVM启动的时间开始增加。如果你找到你自己常用的Maven目标,Maven Console将通过启动JVM一次为来节省时间。
生成Eclipse项目
我打赌你一定想在IDE下工作。Maven通过插件来与Eclipse,InelliJ,IDEA,JBuilder,JDeveloper以及Emacs集成。Maven很好的与全部这些工作集成,本实验关注