maven-war-plugin

Apache Maven WAR Plugin

The WAR Plugin is responsible for collecting all artifact dependencies, classes and resources of the web application and packaging them into a web application archive.

“打包“这个词听起来比较土,比较正式的说法应该是”构建项目软件包“,具体说就是将项目中的各种文件,比如源代码、编译生成的字节码、配置文件、文档,按照规范的格式生成归档,最常见的当然就是JAR包和WAR包了,复杂点的例子是Maven官方下载页面的分发包,它有自定义的格式,方便用户直接解压后就在命令行使用。作为一款”打包工具“,Maven自然有义务帮助用户创建各种各样的包,规范的JAR包和WAR包自然不再话下,略微复杂的自定义打包格式也必须支持,本文就介绍一些常用的打包案例以及相关的实现方式,除了前面提到的一些包以外,你还能看到如何生成源码包、Javadoc包、以及从命令行可直接运行的CLI包。

任何一个Maven项目都需要定义POM元素packaging(如果不写则默认值为jar)。顾名思义,该元素决定了项目的打包方式。实际的情形中,如果你不声明该元素,Maven会帮你生成一个JAR包;如果你定义该元素的值为war,那你会得到一个WAR包;如果定义其值为POM(比如是一个父模块),那什么包都不会生成。除此之外,Maven默认还支持一些其他的流行打包格式,例如ejb3和ear。你不需要了解具体的打包细节,你所需要做的就是告诉Maven,”我是个什么类型的项目“,这就是约定优于配置的力量。

对应于同样的package生命周期阶段,Maven为jar项目调用了maven-jar-plugin,为war项目调用了maven-war-plugin,换言之,packaging直接影响Maven的构建生命周期。了解这一点非常重要,特别是当你需要自定义打包行为的时候,你就必须知道去配置哪个插件。

war plugin的常用配置参数

archiveClasses配置项

该配置的值为true|false,默认是false。表示是否将class进行打包。
正常情况下war类型的工程,java代码编译后的类文件会放到WEB-INF/classes目录下面,散装。 当该参数配置为true时,会将所有的class打包为一个jar,jar的名字与war的名字一致(除了后缀)。然后把这个jar放到WEB-INF/lib目录下,此时WEB-INF/classes目录下是空的。

attachClasses配置项

该配置的值为true|false,默认是false。表示在发布war包的时候是否同时发布一个jar包(只有classes,不包含页面相关文件)。
正常情况下war类型的工程,当我们执行install或者deploy的时候build出一个war包,安装到本地或者发布到远程。
当该参数配置为true时,除了war包外还会多出一个jar包,不过该jar包的classifier默认为classes。

overlays配置节点

overlays配置的作用是,将指定war包中的内容与当前项目进行合并。合并策略:如果存在同名冲突,则使用当前项目中的文件。 overlay的具体配置项(include|exclude)可以指定包含或者排除特定模式的文件。

配置示例

多war合并

archiveClasses和attachClasses参数可以同时配置为true。此时打包文件中含有lib,不含classes。发布时会同时发布classifier为classes的jar包。

如果当前工程A需要从B工程的war包中合入页面文件,同时代码中也要使用B的类文件。工程B包含配置如下:

1
2
3
4
5
6
7
8
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>

工程A包含配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<dependencies>
<dependency>
<groupId>groupB</groupId>
<artifactId>B</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>classes</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>groupB</groupId>
<artifactId>B</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<overlays>
<overlay>
<groupId>groupB</groupId>
<artifactId>B</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>

可注意如果同名的文件夹会进行合并,不合并空文件夹。

把class文件打包成jar,怎么排除resources目录?

正常情况下war类型的工程,java代码编译后的类文件会放到WEB-INF/classes目录下面,散装。 当archiveClasses参数配置为true时,会将所有的class打包为一个jar,jar的名字与war的名字一致。然后把这个jar放到WEB-INF/lib目录下,此时WEB-INF/classes目录下是空的,但如果想在war包的WEB-INF/classes中保留logback.xml配置文件,该怎么做?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archiveClasses>true</archiveClasses>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF/classes</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>

对项目进行动态打包,不同的环境使用不同的配置文件打包

demo 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
project/
`-- src
|-- main
| |-- java
| |-- resources
| | |-- local
| | | |-- logback.xml
| | | |-- spring-dataSource.xml
| | | `-- variable.propertes
| | |-- product
| | | |-- logback.xml
| | | |-- spring-dataSource.xml
| | | `-- variable.propertes
| | `-- qa
| | |-- logback.xml
| | |-- spring-dataSource.xml
| | `-- variable.propertes
| |-- webapp
`-- test
1
2
maven package –P local 开发环境
maven package –P product 生产环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<profiles>
<profile>
<id>local</id>
<properties>
<package.environment>local</package.environment>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>product</id>
<properties>
<package.environment>product</package.environment>
</properties>
</profile>
</profiles>
<build>
<resources>
<!-- class文件打包成jar包,排除相关配置文件和jrebel配置文件 -->
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>local/*</exclude>
<exclude>product/*</exclude>
<exclude>rebel.xml</exclude>
</excludes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!-- 区别dev环境与生产环境logback.xml配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archiveClasses>true</archiveClasses>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>src/main/resources/${package.environment}</directory>
<filtering>true</filtering>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

demo 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
project/
`-- src
|-- main
| |-- java
| |-- env
| | |-- dev
| | | |-- log4j.properties
| | | |-- spring-dataSource.xml
| | | `-- variable.propertes
| | |-- prod
| | | |-- log4j.properties
| | | |-- spring-dataSource.xml
| | | `-- variable.propertes
| | `-- qa
| | |-- log4j.properties
| | |-- spring-dataSource.xml
| | `-- variable.propertes
| |-- resources
| `-- webapp
`-- test
1
2
mvn clean package -P dev
mvn clean package -P qa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>demo Maven Webapp</name>
<groupId>webapp</groupId>
<artifactId>webapp</artifactId>
<scm>
<connection>scm:svn:http://127.0.0.1/dummy</connection>
<developerConnection>scm:svn:https://127.0.0.1/dummy</developerConnection>
<tag>HEAD</tag>
<url>http://127.0.0.1/dummy</url>
</scm>
<properties>
<spring-version>3.1.0.RELEASE</spring-version>
</properties>
<build>
<finalName>${final.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<overlays>
<overlay>
<groupId>TransactionResource</groupId>
<artifactId>TransactionResource</artifactId>
<excludes>
<exclude>WEB-INF/web.xml</exclude>
</excludes>
</overlay>
</overlays>
<webResources>
<resource>
<directory>${runtime.env}</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
……
</dependencies>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<runtime.env>src/main/env/dev</runtime.env>
<final.name>webapp</final.name>
</properties>
<dependencies>
<dependency>
<groupId>com.eightqiu</groupId>
<artifactId>CodeCmns</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>qa</id>
<properties>
<runtime.env>src/main/env/qa</runtime.env>
<final.name>webapp_${buildNumber}</final.name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<format>{0,date,yyyyMMdd}</format>
<items>
<item>timestamp</item>
</items>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
</plugin>
</plugins>
</reporting>
<dependencies>
<dependency>
<groupId>com.eightqiu</groupId>
<artifactId>CodeCmns</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>prod</id>
<properties>
<runtime.env>src/main/env/prod</runtime.env>
<final.name>webapp</final.name>
</properties>
<dependencies>
<dependency>
<groupId>com.eightqiu</groupId>
<artifactId>CodeCmns</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>