安装过程
略~
参见:Maven安装
Maven的配置
Maven安装完成之后,需要进行一些自定义的配置,以后用起来也更方便。
官方文档给出的配置方式有三个级别:
1、环境变量级别:MAVEN_OPTS
这个变量包含了运行Maven的JVM的启动参数,同时可以为Maven提供额外的全局选项,例如JVM的内存设置:-Xms256和-Xmx512m。
这种配置一般出现在build一些大型项目的时候,比如运行mvn eclipse:eclipse,经常会出现因为maven项目过大,导致内存不足java栈溢出的error,这种情况下,就可以修改这两个参数增大内存。
2、settings.xml 文件:
该文件位于用户家目录下的.m2文件夹下,它包含了用户所有Maven项目的共享配置。
3、.mvn 文件夹:
位于Maven项目的根目录下,文件maven.config和extensions.xml包含了项目运行Maven的特殊配置。
settings.xml
我们重点来看settings.xml文件。
settings.xml中的settings元素包含了一些子元素,这些子元素定义的值用来以多种方式配置Maven的运行,比如pom.xml,但这些元素不应该和任何特定的项目绑定。这些值例如:本地仓库位置、远程仓库服务器和验证信息。
settings.xml可能会存在这两个地方:
1. Maven 安装目录:${maven.home}/conf/settings.xml
2. 用户家目录:${user.home}/.m2/settings.xml
第一个settings.xml也叫作全局配置,后者叫作用户配置。如果两者都存在,它们的内容会被合并,并且用户配置优于全局配置。
注: 如果你需要从零开始创建用户自定义配置,最简单的方式是拷贝安装目录下的settings.xml模板文件到用户家目录下的.m2文件夹下。Maven的默认settings.xml是一个包含了注释和例子的模板文件,你稍事修改就可以用了。
这里有setting元素下的一些顶级元素的概览:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>
settings.xml中的内容中可以使用如下的表达式:
${user.home} and 和其他系统属性(始于 Maven 3.0)
${env.HOME} 等其他环境变量
注:定义在settings.xml的profiles元素中的属性不能使用
详细设置
简单值
多半的顶级配置元素都是简单值,代表描述构建系统的元素的取值范围。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>${user.home}/.m2/repository</localRepository>
<interactiveMode>true</interactiveMode>
<usePluginRegistry>false</usePluginRegistry>
<offline>false</offline>
...
</settings>
- localRepository: 这个值代表构建系统的本地仓库系统的路径。默认的值是${user.home}/.m2/repository。这个元素在主构建服务器要求用户登录时,从公用本地仓库进行构建就非常有用。
- interactiveMode:是否以交互方式运行Maven,true允许,false不允许,默认为true。
- usePluginRegistry:Maven是否应该使用${user.home}/.m2/plugin-registry.xml file 管理插件版本,默认为false。注意:对于Maven的2.0版本,plugin-registry.xml文件不起作用。
- offline:构建系统是否应该以离线模式进行操作,默认为false。这个元素在构建服务器由于网络配置或者安全问题而无法连接远程仓库时非常有用。
Plugin Groups
这个元素包含了一个pluginGroup 列表,每个pluginGroup包含一个groupId。命令行中使用一个未给出groupId的plugin时,会搜索这个列表。这个列表自动包含org.apache.maven.plugins和org.codehaus.mojo。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
...
</settings>
举个栗子,利用上述配置,Maven命令行可能会用一个简短的
mvn jetty:run 来替代执行
org.mortbay.jetty:jetty-maven-plugin:run
这个特性非常有用,我们随处可见这种用法,我们自己写的插件由于groupId和artifactId加上version比较长,就会用到这样的配置来“缩短”命令。
Servers
POM的repositories和distributionManagement元素定义了下载和部署的仓库。然而,有些特定的配置如username和password不应该随着pom.xml一块儿发行。这类型的信息应该只存于构建服务器的settings.xml文件中。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<servers>
<server>
<id>server001</id>
<username>my_login</username>
<password>my_password</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<passphrase>some_passphrase</passphrase>
<filePermissions>664</filePermissions>
<directoryPermissions>775</directoryPermissions>
<configuration></configuration>
</server>
</servers>
...
</settings>
id: 这里的服务器ID(不是用来让用户登录的)和Maven要连接的repository/mirror元素的id一致。
username, password: 这俩元素成对出现,提供服务器验证所需的登录名和密码。
privateKey, passphrase: 和前两个元素一样,privateKey和passphrase也成对出现,它们指定了一个到private key的路径
(默认是${user.home}/.ssh/id_dsa) 和一个口令,如果被要求使用的话。口令和密码元素将来可能会被加密,不过现在它们只能以明文在settings.mlx中出现。filePermissions, directoryPermissions: 当一个仓库文件或者目录在部署的时候被创建,它们可以被使用。它们的合法值是一个三位数的*nix(Unix、linux)中文件的权限,比如664或者775。
注:如果你使用了一个private key 登录到服务器,确保你省略了password元素。否则,它自己将被忽略掉。
Repository 的 Mirrors
通过仓库,你可以指定从哪里下载特定的artifacts,比如依赖和Maven插件。仓库可以在项目内部指定,也就意味着,如果你有私有的自定义仓库,这些仓库允许你通过正确的设置很容易地进行项目的共享。然而,你可能有需要为一个特殊的仓库指定一个镜像,而不用改变编项目的文件。
下面给出一些使用镜像的理由:
- 网络上存在一个地理位置更近,下载速度更快的同步镜像服务器。
- 你想用自己的内部仓库替换一个特殊的仓库,对内部仓库你有更大的控制权。
- 你想运行一个仓库管理器来提供到镜像服务器的本地缓存,需要使用镜像的URL地址来替代。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<mirrors>
<mirror>
<id>planetmirror.com</id>
<name>PlanetMirror Australia</name>
<url>http://downloads.planetmirror.com/pub/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
...
</settings>
- id, name: 唯一标识符和用户友好的镜像名称。id用来区分不同的mirros元素,当连接到镜像的时候,从区域中获取相应的凭证。
- url: 镜像的基地址。 构建系统将使用这个基地址连接到一个仓库,恶而不是使用原始的仓库地址。
- mirrorOf: 这个镜像的仓库id。例如,指向Maven中央仓库(https://repo.maven.apache.org/maven2/)的central。更多高级的映射,像repo1,repo2或者*,!inhouse都是可能的。这个不是用来匹配mirror id的。
Note that there can be at most one mirror for a given repository. In other words, you cannot map a single repository to a group of mirrors that all define the same<mirrorOf>
value. Maven will not aggregate the mirrors but simply picks the first match. If you want to provide a combined view of several repositories, use a repository manager instead.
注:一个给定的repository最多只能有一个mirror镜像。也就是说,你不能为一个repository指定<mirroOf
>元素值相同的一组镜像。Maven不会合并这些镜像,只会简单地挑选第一个匹配到的。如果你想提供一个若干仓库的组合视图,请用一个仓库管理器来替代。
Maven构建的生命周期
构建生命周期基础
Maven的核心基础是构建生命周期这个概念。也就是说,对于构建的过程和分发一个特定的artifact(项目)有着明确的定义。
对于使用Maven构建项目的人,只需要学习必要的一小部分构建Maven项目的命令,POM文件就会确保他们得到想要的结果。
Maven有这些内置的构建生命周期:default
、clean
和site
。
Default 生命周期处理你的项目部署;Clean 生命周期处理项目的清理;而Site生命周期负责创建你项目的站点文档。
构建生命周期是由多个阶段(Phases)组成
每一个构建生命周期都是由不同的的构建时期列表构成的,其中的每一个构建阶段代表了生命周期中的一个stage。
例如,默认生命周期由以下的phases构成(完整的生命周期phase列表,请参考Lifecycle Reference):
1. validate - 验证项目是否正确,以及所有必要的信息是否可用
2. compile - 编译项目的源码
3. test - 使用合适的单元测试框架运行编译后的代码。这些测试不应该要求代码是已经打包的或者部署的。
4. package - 将编译后的代码和包打进发行包,例如JAR包
5. verify - 对集成测试的结果进行任意的检查,确保质量条件达标
6. install - 安装发行包到本地仓库中,可以为本地的其他项目所用
7. deploy - 构建环境完成,拷贝最终生成的包到远程仓库中共享给其他开发人员和项目使用。
这些生命周期的阶段(包括其他未在这里作展示的生命周期)有序地未执行来完成默认生命周期的构建。给定上述的生命周期阶段,也就是说使用默认的生命周期,Maven首先会验证项目,然后尝试编译源码,跑测试用例,打包成二进制(比如jar),运行包的集成测试,验证集成测试,安装和验证包到本地仓库,然后部署包(比如jar包)到远程仓库。
常用命令行调用
在开发环境中,使用下列的调用来构建和安装artifacts到本地仓库。
mvn install
这个命令会在执行安装之前,按顺序执行默认生命周期中的每个阶段(validate, compile, package,等等)。你只需要指定最后要执行的phase即可,像这里我们使用的 install
。
在构建环境中,使用下列的调用,干净地构建和部署artifacts到共享仓库中。
mvn clean deploy
一个构建阶段(Phase)由多个插件的Goal组成
然而,即便是一个build phase代表构建生命周期中的一个具体步骤,它实行这些责任的方式仍然是会变化的。这个取决于插件的目标(goals)绑定到何种构建阶段。
一个插件的goal代表一个具体的任务(比构建阶段粒度更细的一个概念),这个任务作用于构建和管理项目上。它可能会绑定到零个或者更多的构建阶段上。一个未绑定到任何构建阶段上的goal,可以在构建生命周期之外被直接调用。执行的顺序依赖于goal(s)和build phase(s)被调用的顺序。举个栗子,考虑如下的一个命令,clean和package参数是构建阶段,而dependency:copy-dependencies 是一个goal (属于某个插件的).
mvn clean dependency:copy-dependencies package
如果这个要执行,clean阶段会先被执行(意味着,它会执行clean生命周期之前的所有阶段,包括clean阶段自己),然后才是dependency:copy-dependencies 目标,最后执行package阶段(和它之前的默认生命周期的所有阶段)
还有,如果一个goal绑定到一个或者更多的构建阶段,这个gaol可以在所有这些阶段被调用。
此外,一个构建阶段还可以有零个或者多个绑定的goal。如果一个构建阶段没有goal是绑定到它,构建阶段不会执行。然而如果有一个或者多个goal绑定到它上它会执行所有的goal。
(注意:在Maven2.0.5以及以上的版本中,多个goal绑定到一个阶段的执行顺序会和他们在POM中声明的顺序一致,然而,不支持同一个插件的多个实例。在Maven2.0.11及以上的版本中,一个插件的多个实例是作为一组一起执行,是有顺序的。)
一些不常在命令行中调用的阶段
命名为hyphenated-words的阶段(pre-, post-, or process-*),不经常从命令行直接调用。这些阶段按顺序排好构建,产生除构建之外无用的中间结果。在调用集成测试的情况下,环境可能被置于挂起的状态。
代码覆盖率工具诸如Jacoco和执行容器插件例如Tomcat, Cargo和Docker绑定goal到pre-integration-test阶段
,来准备集成测试容器环境。这些插件也会绑定goal到post-integration-test phase 来收集覆盖数据或者销毁集成测试容器。
Failsafe 和代码覆盖插件绑定goals到集成测试和验证阶段。net的结果是可以在verify阶段之后可用的测试和覆盖率报告。如果集成测试被命令行调用,不会生成报告。更糟的是,集成测试容器环境被置于挂起状态;Tomcat web服务器或者Docker实例被置于运行状态,而Maven甚至不会停止自身。
设置你的项目使用构建生命周期
构建声明周期用起来很简单,但是当你为一个项目创建一个Maven构建的时候,你将如何为这每个构建阶段分配任务?
Packaging
首先,最常见的方式是,通过设置项目的pom文件中的元素。一些有效的packaging值有jar、war、ear和pom。如果packaging值未指定,它默认是jar。
每个packaging包含一个绑定到特定阶段的goal列表。例如,jar packaging会绑定如下的goal到默认生命周期的构建阶段。
phase | goal |
---|---|
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar |
install | install:install |
deploy | deploy:deploy |
这几乎是最标准的绑定;然而,一些packaging处理它们的方式不一样。例如,一个纯metadata项目(packaging值是pom)仅绑定goals到install和deploy阶段(关于其他packaging类型的goal-to-build-phase的一个完整列表,请参考Lifecycle_Reference)。
注意,对于一些可用的packaging类型,你可能还需要在你的POM的<build>
元素中包含一个特殊的插件,为这个插件指定<extensions>true</extensions>
。一个例子说的是一个插件要求是Plexus插件,它提供了plexus应用和plexus服务包装。
插件
第二种添加goal到phase的方式是在你的项目中配置插件。插件本身是一个提供goal给Maven的打包好的成品(artifacts)。另外,一个插件可能包含一个或多个goal,一个goal就代表这个插件的某个方面的功能。例如, Compiler 插件就有两个goal:compile and testCompile。前者编译你的主程序源码,后者编译你的测试源码。
你会在后边的章节中看到,插件可以包含指明一个goal应该绑定到哪个phase的信息。注意到添加插件本身信息还不够——你必须同时指定goals作为构建的一部分。
配置的goals会被添加到已经绑定了被packaging选择的生命周期中的goal。如果不止一个goal绑定到特定的阶段,使用的顺序是packaging中的在先执行,后面才是POM中配置的。注意,你可以使用<executions>
元素获取更多在特定goals上的控制权。
例如,Modello插件默认绑定它的goal modello:java
到generate-sources
阶段(注意:modello:java goal用来生成Java源代码)。所以,为了使用Modello插件从一个model生成源码并整合进build,你会在你POM的的部分添加如下的片段:
...
<plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<configuration>
<models>
<model>src/main/mdo/maven.mdo</model>
</models>
<version>4.0.0</version>
</configuration>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
...
你可能会在想,为什么<executions>
会出现在这里?正是因为如此,你才可能根据的不同配置多次运行相同的goal,如果需要的话。单独的executions也可以被分配一个ID,这样在继承的过程中,或者应用程序的配置过程中,你可以控制一个goal配置是合并还是转换成一个额外的execution。
当给定多个executions匹配一个特定的phase的时候,他们会按照POM中指定的顺序被执行,继承的executions会先运行。
说到modello:java,它仅在generate-sources 阶段有意义。但是一些goals可以在不止一个phase中使用,而且,可能不存在一个明确的缺省值。对于这些情况,你可以自己指定phase。例如,假如你有一个display:time的goal,用来输出当前时间到命令行,并且,你想要它运行在 process-test-resources
阶段,指明合适开始测试。配置会像这样:
...
<plugin>
<groupId>com.mycompany.example</groupId>
<artifactId>display-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>time</goal>
</goals>
</execution>
</executions>
</plugin>
...
生命周期参考——Lifecycle Reference
下面展示了default,clean和site生命周期的所有的构建阶段,每个阶段会被从开始位置按顺序一直执行到当前指定点。
Clean 生命周期:
phase | description |
---|---|
pre-clean | execute processes needed prior to the actual project cleaning |
clean | remove all files generated by the previous build |
post-clean | execute processes needed to finalize the project cleaning |
默认生命周期
阶段 | 描述 |
---|---|
validate | validate the project is correct and all necessary information is available. |
initialize | initialize build state, e.g. set properties or create directories. |
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 |
process-test-classes | post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. For Maven 2.0.5 and above. |
test | run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed. |
prepare-package | perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. (Maven 2.1 and above) |
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. |
Site 生命周期
阶段 | 描述 |
---|---|
pre-site | execute processes needed prior to the actual project site generation |
site | generate the project’s site documentation |
post-site | execute processes needed to finalize the site generation, and to prepare for site deployment |
site-deploy | deploy the generated site documentation to the specified web server |
内置生命周期绑定
一些阶段会有默认绑定的goals。而且,对于默认的生命周期,这些绑定依赖于packaging 值。这里有一些goal-to-build-phase
绑定。
Clean 生命周期绑定
phase | goals |
---|---|
clean | clean:clean |
默认生命周期绑定 - Packaging ejb / ejb3 / jar / par / rar / war
phase | goals |
---|---|
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war |
install | install:install |
deploy | deploy:deploy |
默认生命周期绑定 - Packaging ear
phase | goals |
---|---|
generate-resources | ear:generate-application-xml |
process-resources | resources:resources |
package | ear:ear |
install | install:install |
deploy | deploy:deploy |
默认生命周期绑定 - Packaging maven-plugin
phase | goals |
---|---|
generate-resources | plugin:descriptor |
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar and plugin:addPluginArtifactMetadata |
install | install:install |
deploy | deploy:deploy |
默认生命周期绑定 - Packaging pom
phase | goals |
---|---|
package | site:attach-descriptor |
install | install:install |
deploy | deploy:deploy |
Site 生命周期 绑定
phase | goals |
---|---|
site | site:site |
site-deploy | site:deploy |