Table of Contents
概述
pom.xml
Maven项目编译
maven项目测试编译及运行
如何生成JAR包并将其安装在本地存储库中?
SNAPSHOT版本是指的什么
如何使用maven plugin
如何在远程存储库中部署jar?
Maven module
Apache Maven是一个软件项目管理工具。 基于项目对象模型( project object model - POM)的概念,Maven可以从一个中心信息管理项目的构建,报告和文档。
Maven,是犹太语里面的一个词,意味知识的积累。最初是为了简化一个名为Jakarta Turbine项目中的构建过程而开始开发的。当时的项目中有几个项目都有自己的Ant构建文件,并且这些文件全部都略有不同,他们使用到的JAR包是在CVS里面检查。 我们想要的是使用一种标准化的方法来构建项目,这种方法能明确定义项目组成的内容,使得项目的发布简便,以及有办法能够跨多个项目共享JAR包的。
后来就诞生了maven工具,现在已经可用于构建和管理任何基于Java的项目。 maven使Java开发人员的日常工作更容易,并且通常有助于理解任何基于Java的项目。
Maven的主要目标是让开发人员在最短的时间内理解开发工作的完整状态。 为了实现这一目标,Maven试图处理以下几个方面的问题:
Maven提供了大量有用的项目信息,这些信息部分来自POM,部分来自项目的来源。 例如,Maven可以提供:
更改直接从源代码管理创建的日志文档 |
交叉引用的来源 |
邮件列表 |
依赖列表 |
单元测试报告包括报道 |
随着Maven的改进,所提供的信息集将得到改善,所有这些对Maven的用户都是透明的。 |
其他产品也可以提供Maven插件,所有这些仍然基于POM。
Maven旨在收集最佳实践开发的现有原则,并使指导项目朝这个方向变得容易。
例如,单元测试的规范,执行和报告是使用Maven的正常构建周期的一部分。 目前的单元测试最佳实践被用作指南:
将测试源代码保存在单独但并行的源代码树中 |
使用测试用例命名约定来定位和执行测试 |
让测试用例设置他们的环境,而不是依赖于自定义构建以进行测试准备。 |
Maven还旨在协助项目工作流程,例如发布和问题管理。 |
Maven还建议了一些关于如何布局项目目录结构的指南,这样一旦你学习了怎样布局,你就可以轻松地驾驭任何其他使用Maven的项目。
Maven为用户端提供了一种简单的方法来更新他们的安装,以便他们可以利用对Maven本身所做的任何更改。出于这个原因,从第三方或Maven本身安装新的或更新的插件已经变得微不足道了。
pom.xml包含此项目的项目对象模型(POM)。 POM是Maven的基本工作单元。 这一点很重要,因为Maven本质上是以项目为中心的,因为一切都围绕着项目的概念。 简而言之,POM包含有关项目的所有重要信息,并且基本上是一站式的,用于查找与项目相关的任何内容。 了解POM很重要,入门maven的工程师有必要了解POM简介。
下面是一个非常简单的POM,但仍然包含了每个POM包含的关键元素,所以我们可以通过每个POM元素来熟悉POM要点:】
4.0.0
com.mycompany.app
my-app
jar
1.0-SNAPSHOT
Maven Quick Start Archetype
http://maven.apache.org
junit
junit
4.11
test
maven的所有属性的信息可以在这里查看。
主要的作用就是管理某些依赖直接的版本号。使用dependencyManagement可以统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,不用每个模块项目都弄一个版本号,不利于管理,当需要变更版本号的时候只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个特殊的版本号时,只需要在自己的模块dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。
1)Dependencies相对于dependencyManagement,所有生命在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。
2)dependencyManagement里只是声明依赖,并不自动实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本
在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 /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约定,可以轻松完成大量工作。
执行以下命令即可:
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] ----------------------------------------------------------------------------
通过下面命令即可打包
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 /my-app/target/classes
[INFO] [resources:testResources]
[INFO] [compiler:testCompile]
Compiling 1 source file to /my-app/target/test-classes
[INFO] [surefire:test]
[INFO] Setting reports 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: /my-app/target/my-app-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing /my-app/target/my-app-1.0-SNAPSHOT.jar to \
/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插件(执行测试所用的插件)会查找包含在具有特定命名约定的文件中的测试。 默认情况下,测试包括:
默认情况下不包括:
以下命令这在启动之前删除包含所有构建数据的target目录
mvn clean
请注意,下面显示的pom.xml文件中的version标记的值具有后缀:-SNAPSHOT。
...
my-app
...
1.0-SNAPSHOT
Maven Quick Start Archetype
...
SNAPSHOT值是指开发分支中的“最新”代码,并不保证代码稳定或不变。 相反,“release”版本中的代码(没有后缀SNAPSHOT的任何版本值)是不变的。
换句话说,SNAPSHOT版本是最终'发布'版本之前的'开发'版本。 SNAPSHOT比其版本“更老”。
在这里还有一点开发经验值得分享。在博主开发一个需要用到spring cloud data flow的项目时,在spring的文档上去学习了一下这个框架,同时准备用文档里的sample来作为练手。但是这些sample却是使用的snapshot的spring版本,结果在本地build这些sample时就一直不成功,后来反复尝试,切换到一个更老的release版本终于成功(个中经历曲折,在这里一笔带过)。得到的启发就是在使用jar包的时候尽量要使用稳定的release版本,而spring的sample也可以自己调整maven的配置来达到调整版本的目的。
maven的profile的功能和spring的profile是类似的,主要都是用于切换不同环境,如开发测试产品的配置文件。
如果我们想要在Maven项目build的时候添加一下自定义的构建内容,那么方式就是通过添加或配置插件plugin来完成。
下面示例使用JDK5作为java编译器的版本
...
org.apache.maven.plugins
maven-compiler-plugin
3.3
1.5
...
这个插件的意思就是实用jdk1.5进行打包。
我们可以注意到Maven中的所有插件看起来都其实和dependency差不多 ,事实上从某些方面来说它们都是依赖。 此插件将自动下载和使用,如果我们想也可以指定特定版本(默认为使用最新版本)。
配置元素将给定参数应用于编译器插件中的每个目标。 在上面的例子中,编译器插件已经被用作构建过程的一部分,这只是改变了配置。 还可以向流程添加新目标,并配置特定的build目标。
要将jar部署到外部存储库,必须在pom.xml中配置repository URL,并在settings.xml中配置连接到存储库的身份验证信息。
以下是使用scp和用户名/密码身份验证的示例:
4.0.0
com.mycompany.app
my-app
1.0-SNAPSHOT
jar
Maven Quick Start Archetype
http://maven.apache.org
junit
junit
4.11
test
org.apache.codehaus.plexus
plexus-utils
1.0.4
src/main/filters/filters.properties
src/main/resources
true
mycompany-repository
MyCompany Repository
scp://repository.mycompany.com/repository/maven2
在执行maven的clean操作时,报以下错误:
failed to execute goal org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean (default-clean) on project ingest: Failed to clean project: Failed to delete
原因是:jar包还在使用当中。
因为博主当时起了另一个服务器使用了这个jar包,因此在maven clean的时候才会失败