Table of Contents
概述
Apache Maven是一个软件项目管理工具。 基于项目对象模型( project object model - POM)的概念,Maven可以从一个中心信息管理项目的构建,报告和文档。
Maven,是犹太语里面的一个词,意味知识的积累。最初是为了简化一个名为Jakarta Turbine项目中的构建过程而开始开发的。当时的项目中有几个项目都有自己的Ant构建文件,并且这些文件全部都略有不同,他们使用到的JAR包是在CVS里面检查。 我们想要的是使用一种标准化的方法来构建项目,这种方法能明确定义项目组成的内容,使得项目的发布简便,以及有办法能够跨多个项目共享JAR包的。
后来就诞生了maven工具,现在已经可用于构建和管理任何基于Java的项目。 maven使Java开发人员的日常工作更容易,并且通常有助于理解任何基于Java的项目。
Maven的主要目标是让开发人员在最短的时间内理解开发工作的完整状态。 为了实现这一目标,Maven试图处理以下几个方面的问题:
- 使构建过程变得简单:虽然使用Maven并不能消除对底层机制的了解,但Maven确实提供了很多对细节的屏蔽。
- 提供统一的构建系统:Maven允许项目使用其项目对象模型(POM)和一组由所有项目共享的插件来构建,从而提供统一的构建系统。 一旦熟悉了Maven项目的构建方式,就会自动了解所有Maven项目的构建方式,从而在尝试了解许多项目时节省大量时间。
- 提供优质的项目信息:
Maven提供了大量有用的项目信息,这些信息部分来自POM,部分来自项目的来源。 例如,Maven可以提供:
更改直接从源代码管理创建的日志文档 |
交叉引用的来源 |
邮件列表 |
依赖列表 |
单元测试报告包括报道 |
随着Maven的改进,所提供的信息集将得到改善,所有这些对Maven的用户都是透明的。 |
其他产品也可以提供Maven插件,所有这些仍然基于POM。
- 提供最佳实践开发指南:
Maven旨在收集最佳实践开发的现有原则,并使指导项目朝这个方向变得容易。
例如,单元测试的规范,执行和报告是使用Maven的正常构建周期的一部分。 目前的单元测试最佳实践被用作指南:
将测试源代码保存在单独但并行的源代码树中 使用测试用例命名约定来定位和执行测试 让测试用例设置他们的环境,而不是依赖于自定义构建以进行测试准备。 Maven还旨在协助项目工作流程,例如发布和问题管理。 Maven还建议了一些关于如何布局项目目录结构的指南,这样一旦你学习了怎样布局,你就可以轻松地驾驭任何其他使用Maven的项目。
- 允许透明迁移到新功能:
Maven为用户端提供了一种简单的方法来更新他们的安装,以便他们可以利用对Maven本身所做的任何更改。出于这个原因,从第三方或Maven本身安装新的或更新的插件已经变得微不足道了。
pom.xml
pom.xml包含此项目的项目对象模型(POM)。 POM是Maven的基本工作单元。 这一点很重要,因为Maven本质上是以项目为中心的,因为一切都围绕着项目的概念。 简而言之,POM包含有关项目的所有重要信息,并且基本上是一站式的,用于查找与项目相关的任何内容。 了解POM很重要,入门maven的工程师有必要了解POM简介。
下面是一个非常简单的POM,但仍然包含了每个POM包含的关键元素,所以我们可以通过每个POM元素来熟悉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/xsd/maven-4.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>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
- project:这是所有Maven pom.xml文件中的顶级元素。
- modelVersion:此元素指示此POM使用的对象模型的版本。模型本身的版本很少发生变化,但如果Maven开发人员认为有必要更改模型,则必须确保使用的稳定性。
- groupId:此元素指示创建项目的组织或组的唯一标识符。 groupId是项目的关键标识符之一,通常基于组织的完全限定域名。例如,org.apache.maven.plugins是所有Maven插件的指定groupId。
- artifactId:此元素指示此项目生成的主工件的唯一基本名称。项目的主要工件通常是JAR文件。像源包这样的辅助工件也使用artifactId作为其最终名称的一部分。 Maven生成的典型工件将具有<artifactId> - <version>。<extension>形式(例如,myapp-1.0.jar)。
- packaging:此元素指示此工件要使用的打包类型(例如JAR,WAR,EAR等)。这不仅意味着生成的工件是JAR,WAR还是EAR,还可以指示要在构建过程中使用的特定生命周期。 (生命周期是我们将在指南中进一步讨论的主题。现在,请记住,项目的指示包装可以在定制构建生命周期中发挥作用。)包装元素的默认值是JAR所以你不必为大多数项目指定这个。
- version:此元素指示项目生成的artifact 的版本。 Maven在很大程度上帮助您进行版本管理,您经常会在一个版本中看到SNAPSHOT指示符,这表明项目处于开发状态。我们将在本指南中讨论快照的使用以及它们如何进一步工作。
- name:此元素指示用于项目的显示名称。这通常用于Maven生成的文档中。
- url:此元素指示可以找到项目站点的位置。这通常用于Maven生成的文档中。
- description:此元素提供项目的基本描述。这通常用于Maven生成的文档中。
maven的所有属性的信息可以在这里查看。
Maven项目编译
在pom.xml的根目录下执行以下命令:
mvn compile
以上面的pom为例它的输出类似下面:
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Quick Start Archetype
[INFO] task-segment: [compile]
[INFO] ----------------------------------------------------------------------------
[INFO] artifact org.apache.maven.plugins:maven-resources-plugin: \
checking for updates from central
...
[INFO] artifact org.apache.maven.plugins:maven-compiler-plugin: \
checking for updates from central
...
[INFO] [resources:resources]
...
[INFO] [compiler:compile]
Compiling 1 source file to <dir>/my-app/target/classes
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 3 minutes 54 seconds
[INFO] Finished at: Fri Sep 23 15:48:34 GMT-05:00 2005
[INFO] Final Memory: 2M/6M
[INFO] ----------------------------------------------------------------------------
首次执行此(或任何其他)命令时,Maven将需要下载完成命令所需的所有插件和相关依赖项。从一个刚创建的"clean"Maven项目执行命令,可能需要一段时间。如果再次执行该命令,Maven项目将在那时已经拥有它所需的内容,因此它不需要下载任何新内容,并且能够更快地执行命令。
从输出中可以看出,编译后的类被放在$ {basedir} / target / classes中,这是Maven采用的另一个标准约定。所以,如果你是一个敏锐的观察者,你会注意到通过使用标准约定,上面的POM非常小,你不必明确告诉Maven你的任何来源在哪里或输出应该去哪里。遵循标准的Maven约定,可以轻松完成大量工作。
maven项目测试编译及运行
执行以下命令即可:
mvn test
执行成功的结果如下:
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Quick Start Archetype
[INFO] task-segment: [test]
[INFO] ----------------------------------------------------------------------------
[INFO] artifact org.apache.maven.plugins:maven-surefire-plugin: \
checking for updates from central
...
[INFO] [resources:resources]
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources]
[INFO] [compiler:testCompile]
Compiling 1 source file to C:\Test\Maven2\test\my-app\target\test-classes
...
[INFO] [surefire:test]
[INFO] Setting reports dir: C:\Test\Maven2\test\my-app\target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
[surefire] Running com.mycompany.app.AppTest
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0 sec
Results :
[surefire] Tests run: 1, Failures: 0, Errors: 0
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 15 seconds
[INFO] Finished at: Thu Oct 06 08:12:17 MDT 2005
[INFO] Final Memory: 2M/8M
[INFO] ----------------------------------------------------------------------------
如何生成JAR包并将其安装在本地存储库中?
通过下面命令即可打包
mvn package
如果查看项目的POM,会注意到生成的包的格式为jar。 查看$ {basedir} / target目录,就将看到生成的JAR文件。如果想在Maven的本地存储库查看到生成的文件(JAR文件)($ {user.home} /.m2 / repository是默认位置),则执行以下命令:
mvn install
执行成功的话可以看到以下输出:
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Quick Start Archetype
[INFO] task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] [compiler:compile]
Compiling 1 source file to <dir>/my-app/target/classes
[INFO] [resources:testResources]
[INFO] [compiler:testCompile]
Compiling 1 source file to <dir>/my-app/target/test-classes
[INFO] [surefire:test]
[INFO] Setting reports dir: <dir>/my-app/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
[surefire] Running com.mycompany.app.AppTest
[surefire] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.001 sec
Results :
[surefire] Tests run: 1, Failures: 0, Errors: 0
[INFO] [jar:jar]
[INFO] Building jar: <dir>/my-app/target/my-app-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing <dir>/my-app/target/my-app-1.0-SNAPSHOT.jar to \
<local-repository>/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Tue Oct 04 13:20:32 GMT-05:00 2005
[INFO] Final Memory: 3M/8M
[INFO] ----------------------------------------------------------------------------
请注意,surefire插件(执行测试所用的插件)会查找包含在具有特定命名约定的文件中的测试。 默认情况下,测试包括:
- **/*Test.java
- **/Test*.java
- **/*TestCase.java
默认情况下不包括:
- **/Abstract*Test.java
- **/Abstract*TestCase.java
以下命令这在启动之前删除包含所有构建数据的target目录
mvn clean
SNAPSHOT版本是指的什么
请注意,下面显示的pom.xml文件中的version标记的值具有后缀:-SNAPSHOT。
<project xmlns="http://maven.apache.org/POM/4.0.0"
...
<groupId>...</groupId>
<artifactId>my-app</artifactId>
...
<version>1.0-SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
...
SNAPSHOT值是指开发分支中的“最新”代码,并不保证代码稳定或不变。 相反,“release”版本中的代码(没有后缀SNAPSHOT的任何版本值)是不变的。
换句话说,SNAPSHOT版本是最终'发布'版本之前的'开发'版本。 SNAPSHOT比其版本“更老”。
如何使用maven plugin
如果我们想要在Maven项目build的时候添加一下自定义的构建内容,那么方式就是通过添加或配置插件plugin来完成。
下面示例使用JDK5作为java编译器的版本
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
...
这个插件的意思就是实用jdk1.5进行打包。
我们可以注意到Maven中的所有插件看起来都其实和dependency差不多 ,事实上从某些方面来说它们都是依赖。 此插件将自动下载和使用,如果我们想也可以指定特定版本(默认为使用最新版本)。
配置元素将给定参数应用于编译器插件中的每个目标。 在上面的例子中,编译器插件已经被用作构建过程的一部分,这只是改变了配置。 还可以向流程添加新目标,并配置特定的build目标。
如何在远程存储库中部署jar?
要将jar部署到外部存储库,必须在pom.xml中配置repository URL,并在settings.xml中配置连接到存储库的身份验证信息。
以下是使用scp和用户名/密码身份验证的示例:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
<filters>
<filter>src/main/filters/filters.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<!--
|
|
|
-->
<distributionManagement>
<repository>
<id>mycompany-repository</id>
<name>MyCompany Repository</name>
<url>scp://repository.mycompany.com/repository/maven2</url>
</repository>
</distributionManagement>
</project>