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
。