另参考:MAVEN 核心POM详解(很详细)
What’s POM?
pom.xml
是
maven
的核心文件,是maven用来build project的configuration file,
就象
Ant
的
build.xml。for most project,
缺省的
pom.xml
包含了一些
default value
,通常情况下你不需要在你的
pom.xml
里设置这些值。例如:
- 缺省的build directory是“target”目录
- 缺省的source directory是“src/main/java”目录
- 缺省的build directory是“src/main/test”目录
pom.xml
的
configuration info
包括:
- Project基本信息,如project version, description, developers, mailing lists
- project dependencies
- 要执行的plugins or goals
- build profiles
下面参考我的第一个maven命令生成的pom.xml来讲解它的配置信息
<project xmlns=
。。。。
>
<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>
project
root element of pom.xml files.
modelVersion
设置
POM version,
类似于设置
project version
,目前好像
maven 2
只允许该值为
4.0.0
groupId
设置
project
的
organization or group
的
ID
,它是
project
的唯一识别之一
(另
1
个是
artifactId
)。
groupId
通常以
full domain name
作为属性值
,例如所有
maven plugins
的
groupId
的属性值为
org.apache.maven.plugins
artifactId
设置当前
project
将生成的
primary artifact
的
unique base name
(
请注意:是
base name
,而不是
name
,因为
artifact name
是由
”<artifactId>-<version>”
组成
,例如
myapp-1.0.jar
)。
packaging
设置
package type to be used by this artifact (e.g. JAR, WAR, EAR, etc.)
。该属性值不仅是用来设置被生成的
artifact
是
JAR, WAR
还是
EAR
,
还用来设置
package artifact
时要
process
的
lifecycle
,即
JAR, WAR, EAR
的
build lifecycle
是不同的
。
packaging
的缺省属性值为
JAR
。如果你的
project
要
package
成
jar
,你不需要设置该属性
version
设置
project
生成的
artifact
的
version
。
Maven
能帮你进行
version management
。
如果你看到该属性值里包含有“
SNAPSHOT
”
string
,则表示该
project
处于开发阶段
,而不是发布阶段。
name
设置
project name
,该属性值通常用于
Maven's generated documentation.
url
设置该
project
的
web site url.
该属性值通常用于
Maven's generated documentation
description
设置
project description
该属性值通常用于
Maven's generated documentation
Super POM
Super POM是Maven's default POM,它设置了maven的基本default value(
例如
build directory
为“
target
”)。
它的所有设置会被你的
project
的
pom.xml
继承,
你如果要覆盖缺省设置,就需要进行显式设置。
下面是super pom content:
<project>
<modelVersion>4.0.0</modelVersion>
<name>Maven Default Project</name>
<repositories>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>target</directory>
<outputDirectory>target/classes</outputDirectory>
<finalName>
${pom.artifactId}-${pom.version}
</finalName>
<testOutputDirectory>target/test-classes</testOutputDirectory>
<sourceDirectory>src/main/java</sourceDirectory>
<scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
</build>
<reporting>
<outputDirectory>target/site</outputDirectory>
</reporting>
</project>
Minimal POM
一个
pom.xml
必须要有的东东是:
- project root
- modelVersion - should be set to 4.0.0
- groupId - the id of the project's group.
- artifactId - the id of the artifact (project)
- version - the version of the artifact under the specified group
例:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
其中的
groupId, artifactId and version
组成了project
的fully qualified artifact name
:
<groupId>:<artifactId>:<version>
,例如上例的
fully artifact name
为
"com.mycompany.app:my-app:1"
在minimal pom里,没有设置<packaging>,那么会使用缺省值:jar。
也没有设置<
repositories>。
如果没有
repositories
属性,就会继承
super pom
的
repositories
配置,
maven
在执行这个
minimal pom
时,就会按从缺省的
repositories
:
http://repo1.maven.org/maven2
下载相关的
dependencies。
Project Inheritance
Project inheritance
是child project
继承parent project
!
pom.xml中能被合并(merge)的elements包括:
- dependencies
- developers and contributors
- plugin lists (including reports)
- plugin executions with matching ids
- plugin configuration
- resources
Super pom
就是project inheritance
最典型的例子。你也可以通过在child project pom.xml里设置<parent> element,从而实现继承parent pom。
The Scenario
我们使用之前的那个artifact, com.mycompany.app:my-app:1. 同时我们还有另外一个artifact, com.mycompany.app:my-module:1. my-module project的pom.xml为:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
然后我们看看这2个artifact的目录结构
.
|-- my-module
| `-- pom.xml
`-- pom.xml
注意:
my-module/pom.xml is the POM of com.mycompany.app:my-module:1 while pom.xml is the POM of com.mycompany.app:my-app:1
The Solution
如果我们想让com.mycompany.app:my-app:1成为com.mycompany.app:my-module:1的parent artifact,我们就需要将com.mycompany.app:my-module:1's POM修改成:
com.mycompany.app:my-module:1's POM
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
通过<parent> element,可以设置pom的parent pom,从而从parent pom里继承一些配置。
另外,如果你想the module的groupId and version设置成和parent一样,那么你可以去掉child pom的groupId and version element。如
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
这样就会继承
parent pom
的
groupId and version
Example 2
The Scenario
Example 1
能够正常运行的先决条件是:
parent project
已经
install to local repository
或者
parent project pom.xml
必须恰好处于
child project pom.xml
的上一级目录。
而如果
parent project
没有
install to repository
或者象下列结构,使用
example 1
的代码是不行的:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
The Solution
对于上面的目录结构(或者其他不属于example 1的结构),child pom.xml需要添加<relativePath> element来设置你的parent project的path。如:
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
Project Aggregation
Project aggregation
是child project
委托parent project
执行。它和project inheritance
很相似,project inheritance
是在child pom.xml
里设置parent project
,而Project aggregation
则是在parent pom.xml
里设置child project
。,
Child project
是通过在parent pom.xml
里定义<module>
来设置Project Aggregation
的。Project Aggregation
意味着在执行parent project
时,也会同时执行定义了aggregation
的child project
。
另外还有一点要注意:
设置了project aggregation的parent project pom.xml必须把<packaging>的值设置为“pom”
Example 3
The Scenario
依然是使用example 1的parent project and child project。
com.mycompany.app:my-app:1's POM
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
com.mycompany.app:my-module:1's POM
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
directory structure
.
|-- my-module
| `-- pom.xml
`-- pom.xml
The Solution
如果我们要把my-module委托给my-app,我们需要修改parent pom.xml如下
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>my-module</module>
</modules>
</project>
Example 4
The Scenario
Example31
能够正常运行的先决条件是:
child project
已经
install to local repository
或者
parent project pom.xml
必须恰好处于
child project pom.xml
的上一级目录。
而如果child project没有install to repository或者象下列结构,使用example 3的代码是不行的:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
The Solution
类似于example 3,但是设置child project的path不同。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>../my-module</module>
</modules>
</project>
Project Inheritance VS Project Aggregation
使用Project Inheritance的情况:如果你有多个maven projects, 而且它们有一些相同的配置,那么你就应该refactor你的projects,把这些相同的配置从projects中提取出来,然后把这些相同配置制作成一个parent project,然后你所有的projects都继承该parent project。Super POM就是最典型的project inheritance例子
使用Project Aggregation的情况:如果你有一组projects常常需要同时进行maven build的操作,那么你就可以创建一个parent project,然后把这组projects作为该parent project的modules,这样你只需要maven parent project即可执行这组projects。一个典型的例子就是:project A是build jar,project B是package war,该war会把project A的jar纳入, project C是package ear,该ear会把project B的war纳入
当然,你可以同时使用
Project Inheritance and Project Aggregation
,即在
parent project
里设置
modules
,同时在
child projects
里设置
parent project
。