Maven
Maven简介
Maven最初的目的是在Jakarta Turbine项目中使构建处理简单化。几个项目之间使用到的Ant build文件差异很小,各个JAR都存入CVS。因此希望有一个标准的方法构建各个工程,清晰的定义一个工程的组成,一个容易的方法去发布项目信息并且去提供一种在各个项目之间共享JAR包。
结果出现了一种功能能用于构建和管理任何基于java的工程。Maven小组希望他们已经做到了一些事情,这将有助于Java开发者更容易的完成每天的工作并且有助于理解任何基于java的项目。
Maven的目标是:
-
使构建过程更容易
-
提供统一构建系统
-
提供高质量的项目信息
-
提供开发的最佳实践指南
-
能无缝的加入新的特性
对Maven的错误理解
-
Maven是一个站点和文档制作工具。
-
Maven扩展了Ant,使其能下载到各种依赖包
-
Maven是一系列可重用的Ant脚本
Maven的版本。
Maven现在主要有Maven 1.x和Maven 2.x,其中现在最新版本是Maven 2.02。
Maven 2完成了对Maven 1的重写。重写的首要目的是要提供了强大的Jave构建和包含API的项目,允许Maven被植入任何地方,尤其是高级别的产品如IDEs、质量工具、报告工具等这些。Maven 2构建生命周期的概念正式化,其比Maven更易扩展。
因此现在我们主要研究的就是Maven 2。
Maven的安装
-
Windows 2000/xp下的安装
-
解压缩maven-2.0.2-bin.zip到你希望安装Maven 2.0.2的所在目录。这里假设你选择了C:\ProgramFiles\Apache Software Foundation\maven-2.0.2.
-
将C:\Program Files\Apache Software Foundation\maven-2.0.2\bin目录加入到你的%path%环境变量中。
-
同时,确认JAVA_HOME是否正确设置成功。
-
运行 mvn --version 确认是否安装成功。
显示Maven version: 2.0.2 则表示安装成功。
-
基于Unxi-based的操作系统(Linux,Solaris and Mac OS X)
-
解压缩发布包到你希望安装Maven 2.0.2的所在目录。这里假设你选择了/usr/local/maven-
-
将/usr/local/maven-2.0.2/bin目录加入到你的path环境变量中,例如:PATH=/usr/local/maven-2.0.2y/bin: $PATH。
-
同时,确认JAVA_HOME是否正确设置成功。
-
运行 mvn --version 确认是否安装成功。
显示Maven version: 2.0.2 则表示安装成功。
Maven主要功能列表
Maven是一种对项目的管理工具,它提供了一种方式来管理以下项目中涉及到的工作内容,同时以下也是Maven的主要功能:
-
构建项目(Builds)
-
文档编制(Documentation)
-
报告(Reporting)
-
依赖管理(Dependencies)
-
配置管理(SCMs)
-
发布管理(Releases)
构建项目
-
首先创建一个Maven工程
Maven可用于构建java应用工程和java web应用工程。
-
WebApp
mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-webapp
-DarchetypeArtifactId=maven-archetype-webapp
my-webapp
|-- pom.xml
`-- src
`-- main
|-- webapp
| |-- WEB-INF
| | `-- web.xml
| `--index.jsp
`-- resources
其他的目录则需要自己补充。
其pom.xml文件内容如下:
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Maven Webapp Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>my-webapp</finalName>
</build>
</project>
|
-
App
mvn archetype:create -DgroupId=com.mycompany.ap -DartifactId=my-app
命令正确执行后,生成如下目录:
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
其pom.xml文件内容如下:
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.ap</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
|
-
Maven项目的标准目录介绍
Maven提倡使用一个共同的标准目录结构,使开发人员能在熟悉了一个Maven工程后,对其他的Maven工程也能清晰了解。这样做也省去了很多设置的麻烦。
以下的文档介绍是Maven希望的目录结构,并且也是目录创建工程是采用的目录结构。Maven推荐大家尽可能的遵守这样的目录结构。
src/main/java
|
Application/Library sources
|
src/main/resources
|
Application/Library resources
|
src/main/filters
|
Resource filter files
|
src/main/assembly
|
Assembly descriptors
|
src/main/config
|
Configuration files
|
src/main/webapps
|
Web application sources
|
src/test/java
|
Test sources
|
src/test/resources
|
Test resources
|
src/test/filters
|
Test resource filter files
|
src/site
|
Site
|
LICENSE.txt
|
Project's license
|
README.txt
|
Project's readme
|
在顶级目录上是工程的描述文件pom.xml(如果使用Ant则还包括其他属性文件,maven.xml或build.xml),另外还包括提供给最终用户的文件,如,README.txt, LICENSE.txt等等。
顶级目录还包括两个子目录:src,target。顶级目录下可能出现的其他目录仅仅是CVS或.svn和其他多模块工程的工程目录,最好不要再有其他目录。
Target目录是所有工程编译构建的输出目录。
Src目录包含所有工程的源码文件,配置文件,资源文件等等。它下面的子目录一般包含main(主要的工程源文件),test(测试文件),site(项目站点文件)。
-
项目构建的生命周期的介绍
Maven 2是围绕着构建生命周期概念设计的。这意味着,构建或者发布的过程已经被清晰的定义了。
当我们使用Maven构建工程时,我们只需要了解几个Maven定义好的命令即可,其他的工作则交给POM来完成。
以下给出Maven提供的构建生命周期列表:
validate
|
validate the project is correct and all necessary information is available.
|
generate-sources
|
generate any source code for inclusion in compilation.
|
process-sources
|
process the source code, for example to filter any values.
|
generate-resources
|
generate resources for inclusion in the package.
|
process-resources
|
copy and process the resources into the destination directory, ready for packaging.
|
compile
|
compile the source code of the project.
|
process-classes
|
post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.
|
generate-test-sources
|
generate any test source code for inclusion in compilation.
|
process-test-sources
|
process the test source code, for example to filter any values.
|
generate-test-resources
|
create resources for testing.
|
process-test-resources
|
copy and process the resources into the test destination directory.
|
test-compile
|
compile the test source code into the test destination directory
|
test
|
run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.
|
package
|
take the compiled code and package it in its distributable format, such as a JAR.
|
pre-integration-test
|
perform actions required before integration tests are executed. This may involve things such as setting up the required environment.
|
integration-test
|
process and deploy the package if necessary into an environment where integration tests can be run.
|
post-integration-test
|
perform actions required after integration tests have been executed. This may including cleaning up the environment.
|
verify
|
run any checks to verify the package is valid and meets quality criteria.
|
install
|
install the package into the local repository, for use as a dependency in other projects locally.
|
deploy
|
done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
|
因此,当我们构建一个项目时,只需要了解自己希望做什么,然后执行以上对应的生命周期即可。
例如,我们希望编译我们的工程。在命令行状态下进入到工程的pom.xml文件所在的目录中,使用命令:mvn compile;希望构建打包我们的工程,使用mvn package即可。
当然了,maven的构建生命周期也是可以扩展和自定义的,这里就先不做介绍了。
-
pom.xml的介绍
pom.xml包含了一个项目的项目对象模型(POM)。项目对象模型(POM)是Maven工作的基本单元。请记住,这个是非常重要的,因为POM包含了工程的非常重要的信息块,并且基本上包含了和项目相关的任何要素。
让我们熟悉一下pom.xml包含的基本项:
-
poject 这是pom.xml的顶级元素。
-
modelVersion 这是元素指出了这个POM使用的是那个版本的对象模型。这个模型的版本自身么是经常改变的,但这种改变是为了使模型更加的稳定。
-
groupId 这个元素指出创建这个工程的组织或团队的唯一标识,并且这个也是一个项目的关键标识,推荐使用这个组织或团队的完整域名。例如:org.apache.maven.plugins是为Maven plug-ins定义的groupId。
-
artifactId 这个元素指出这个工程的主要制品的基本名称。一个工程的主要制品如果是jar文件,次要制品如果是源码包,则次要制品的名称的一部分也使用artifactId。典型的制品名称使用这样的格式:<artifactId>-<version>.<extension>(例如,myapp-1.0.jar)。
-
packaging 这个元素指出制品的类型(例如:JAR,WAR,EAR等等)。这个元素不仅仅指示出制品的类型,同时也指示出工程构建过程中的部分生命周期。Packaging的默认值是JAR。
-
version 这个元素指出这个项目产生的制品的版本号,Maven在帮助开发人员管理版本号时走了很长的路,以后你将经常看到SNAPSHOT在一个版本中,这个表示一个工程仍然在开发状态。
-
name 这个元素指出这个工程显示的名称。这个常用于Maven产生的文档中。
-
url 这个员算指出在哪里能发现工程的站点。这个常用于Maven产生的文档中。
-
desription 这个元素提供了这个工程基本的描述。这个也常用于Maven产生的文档中。
以上只是pom.xml中的一些基本项,完整的pom.xml的元素介绍请参考:
http://maven.apache.org/maven-model/maven.html
文档编制
-
文档创建:
对于如何创建和编制文档,maven有一个简单的示例命令:
mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-site
|
执行了以上命令后,我们将得到这样一个目录结构:
my-app
|-- pom.xml
`-- src
|-- site
|-- apt
| |-- format.apt
| `-- index.apt
|-- fml
| `-- faq.fml
|-- fr
| |-- apt
| | |-- format.apt
| | `-- index.apt
| |-- fml
| | `-- faq.fml
| `-- xdoc
| `-- xdoc.xml
|-- site.xml
|-- site_fr.xml
`-- xdoc
`-- xdoc.xml
|
你现在可以看到一个$basedir/src/site目录,以及它包含的一些站点描述文件(site.xml,site_fr_xml),和各种maven支持的文档格式相对应的目录和示例文档都已经产生。
以上的创建只是示例,我们自己创建时就没有命令行使用了,只能按照上面的目录结构创建我们需要的文档,并在文档中写入我们工程的信息。
让我们再来看看maven所支持的文档格式。
-
文档格式:
Maven支持3种文档格式:
这个是一种简单快捷的,基于original Anakia format的文件格式。
“Almost Plain Text”,(接近普通文本格式),这是一种允许你采用接近普通文本格式的方式简单的写出类似于wiki格式的结构性文档。
如果你对此很感兴趣,请参考完整的APT format的书写规范
http://maven.apache.org/guides/mini/guide-apt-format.html
这个是一种FAQ结构形式的文档格式。
了解了以上的文档格式,我们就可以按照以上文档格式的要求,选用我们喜欢的文档格式编写我们的文档。当编写完成后,我们需要生成所有文档。这里生成文档,maven的处理是生成站点(site),也就是身成html页面,这样所有对此项目感兴趣的人员都可以通过访问此站点来了解所有的信息。生成站点的命令是:
-
文档国际化:
当然,你可能早就想到文档国际化的问题,这里maven也早就处理了。在pom.xml中
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<locales>en,fr</locales>
</configuration>
</plugin>
</plugins>
...
|
注意到<locales>en,fr</locales>了吗?这里就支持了英语(en)和法语(fr)两种语言的文档。请注意以下生成的目录,由于英语是在第一个,属于默认语言,所以$basedir/src/site目录下并没有en的文件夹,而有fr的文件夹,而且这个文件夹里包含了maven支持的文档格式相对应的目录和示例文档。
报告设置
Maven有多个报告能添加在你的文档站点中,来显示项目当前的状态,这些报告采用插件的形式可在项目中配置。
为了为你的文档站点增加这些报告,必须增加reporting部分在pom.xml中,下面这个为标准的项目信息报告插件在pom.xml中的配置。
<project>
...
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
</plugins>
</reporting>
...
|
Maven在执行mvn site命令时,除了产生开发人员编制的文档信息外,根据pom.xml中设置的报告,会同时生成这个项目信息的报告文档。并且这个是默认的生成项。
这个默认的生成项将根据项目的信息生成以下报告:
根据笔者测试,以上信息均是在pom.xml进行设置的。
-
持续集成信息根据以下配置信息生成:
<ciManagement>
<system/>
<url/>
<notifiers>
<notifier>
<type/>
<sendOnError/>
<sendOnFailure/>
<sendOnSuccess/>
<sendOnWarning/>
<address/>
<configuration/>
</notifier>
</notifiers>
</ciManagement>
|
-
依赖性信息根据以下配置信息有关
<dependencies>
<dependency>
<groupId/>
<artifactId/>
<version/>
<type/>
<classifier/>
<scope/>
<systemPath/>
<exclusions>
<exclusion>
<artifactId/>
<groupId/>
</exclusion>
</exclusions>
<optional/>
</dependency>
</dependencies>
|
<issueManagement>
<system/>
<url/>
</issueManagement>
|
<mailingLists>
<mailingList>
<name/>
<subscribe/>
<unsubscribe/>
<post/>
<archive/>
<otherArchives/>
</mailingList>
</mailingLists>
|
笔者在pom.xml中设置以上信息后,运行mvn site总会报错。如果哪位了解到报错原因请告诉我,谢谢。zhangxl@sintal.cn
<licenses>
<license>
<name/>
<url/>
<distribution/>
<comments/>
</license>
</licenses>
|
<organization>
<name/>
<url/>
</organization>
|
<developers>
<developer>
<id/>
<name/>
<email/>
<url/>
<organization/>
<organizationUrl/>
<roles/>
<timezone/>
<properties/>
</developer>
</developers>
|
<contributors>
<contributor>
<name/>
<email/>
<url/>
<organization/>
<organizationUrl/>
<roles/>
<timezone/>
<properties/>
</contributor>
</contributors>
|
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
|
默认情况下这些文档将生成在$basedir/src/site目录下。
需要得到其他的报告,则需要配置其他的报告插件。
要想了解更多的信息,请参考以下网页:
http://cvs.peopleware.be/training/maven/maven2/morePlugins.html
依赖管理
这里我们通过使用外部依赖(external dependencies)来大家对maven的依赖管理有一个简单而具体的了解。
当我们在做一个工程的时候,不可能一切都是从空白开始,对于我们做Web应用的来说,使用框架已经司空见惯,而这种对框架的引入使用对于Maven来说,就是工程的依赖。而我们的工程要进行测试,则不能少了对Junit框架的依赖。
依赖管理是maven的一个主要特征,这个是对于用户来说,是Maven令人振奋的一个最著名的特征。对于一个单一的工程来说,依赖管理没有什么困难的,但是当你开始处理多个模块的工程或由10多个甚至上百个模块组成的应用程序时, Maven能帮助你轻松稳定的控制这些大量的依赖。
在pom.xml中dependencies部分列出了所有外部依赖,详细描述了在编译时,测试时,运行时是否需要这个依赖。现在,假定我们的工程只有对Junit的依赖。它的pom.xml文件可能如下:
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
|
从以上pom.xml文件可以看出,定义一个外部依赖(external dependencies)至少需要4个元素:groupId, artifactId, version, and scope。对于groupId, artifactId, version的意思,和前面我们在创建工程时提到的这几个元素的意义相同,这里就不再重复介绍,scope元素指出你的工程如何使用依赖,并且它的值有compile,test和runtime等等。想要了解更多的依赖说明的信息,请看
http://maven.apache.org/maven-model/maven.html
要想了解完整的依赖机制,请看
http://maven.apache.org/guides/introduction/introduction-to-dependency-management.html
有了这些依赖信息,Maven将能在工程构建时引用依赖。
引用的过程是:
首先,在本地仓库(默认的本地仓库地址为:~/.m2/repository)中查找此依赖是否存在。
再次,如果在本地仓库中未发现,则在远程仓库中下载此依赖,并下载到本地仓库中。
最后,通过以上两个步骤就能找到依赖。如果远程仓库无法访问,则可以设置其他远程仓库。具体请看
http://maven.apache.org/guides/introduction/introduction-to-repositories.html
一个简单的例子。比如我们要添加一个log4j到我们的工程中。
首先.需要了解log4j的groupId, artifactId, and version信息。可在google上搜索“site:www.ibiblio.org maven2 log4j”。这样在搜索结果里可以找到/maven2/log4j/log4j (or /pub/packages/maven2/log4j/log4j)这样的目录,在这个目录中有一个文件叫做maven-metadata.xml。这个文件内容如下所示:
-
<metadata>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.1.3</version>
<versioning>
<versions>
<version>1.1.3</version>
<version>1.2.4</version>
<version>1.2.5</version>
<version>1.2.6</version>
<version>1.2.7</version>
<version>1.2.8</version>
<version>1.2.11</version>
<version>1.2.9</version>
<version>1.2.12</version>
</versions>
</versioning>
</metadata>
|
这样我们能找到groupId为log4j,artifactId为log4j,version当然要用最新的,选择1.2.12。scope我们设置为compile。
这样我们使用mvn compile 编译工程时,会看到mvn下载了log4j到我们的本地仓库。
配置管理
Maven的配置管理是作为一个单独的Maven子项目在做。叫做SCM。他是这样介绍的:
MavenSCM支持Maven 2.x插件(例如,maven-release-plugin)和其他工具(例如,Continuum,这个是一个和maven 2.x结合很好的一个持续集成工具。),Maven SCM提供给他们一个公共的API去做配置管理的各种操作。当然了要执行配置管理操作,当然少不了配置滚里工具了。Maven SCM给出了一个列表,说明Maven SCM现在所支持的配置管理工具。
完全支持的配置管理工具
|
CVS
Subversion
Perforce
StarTeam
|
部分支持的配置管理工具
|
ClearCase
File system
Visual Source Safe
|
不支持的配置管理工具
|
Accurev
Aegis
Arch
BitKeeper
ClearCase Multisite
CM Synergy
Code Co-op
Darcs
Monotone
OpenCM
PureCM
Serena PVCS / Dimension
Starteam Enterprise
Svk
Vesta
|
当你选中了上面的一个配置管理工具,你就可以利用Maven 2.x的插件或者集成管理工具进行配置管理了。
-
持续集成工具continuum
continuum是Maven的一个子项目。他是一个构建基于java的工程的持续集成服务器。他支持以下多种工程类型:
-
Maven 1
-
Maven 2
-
Ant
-
Shell scripts
continuum有以下特征
-
下载:
在以下连接处下载此软件
http://maven.apache.org/continuum/download.html
|
安装:
Windows 2000/XP
解压缩continuum-1.0.2-bin.zip到你希望安装Continuum 1.0.2的所在目录。这里假定你安装在C:\Program Files\Apache Software Foundation\continuum-1.0下。
运行:
-
bin/linux/run.sh 如果是UNIX平台
-
bin/solaris/run.sh 如果是Solaris平台
-
bin/win32/run.bat 如果是Windows平台
-
bin/macosx/run.sh 如果是MacOS X平台.
-
bin/plexus.sh 如果是其他平台
当服务器启动成功后,打开浏览器访问:
http://localhost:8080/continuum/
|
注意:由于continuum判断一个工程是否构建成功,是使用一个命令行返回值。而windows平台的用户,这个返回值有问题。因此需要修改以下maven 2的bin/mvn.bat文件。这里可以直接从以下地址下载修改后的文件替换掉即可。
http://maven.apache.org/continuum/scripts/mvn.bat
|
-
添加一个项目到continuum
要添加一个maven 2的项目到continuum,需要写入一个pom url或者导入一个pom.xml,当然导入的这个pom.xml文件中包含了continuum需要的各种信息。
我们来看看导入的pom.xml文件中具体需要包含哪些项:
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
|
<ciManagement>
<system>continuum</system>
<notifiers>
<notifier>
...
</notifier>
</notifiers>
</ciManagement>
|
<notifier>
<type>mail</type>
<configuration>
<address>dev@maven.apache.org</address>
|