Maven常见问题

如何设置代码编译版本

增加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>

如何配置jetty插件

plugins段增加配置

1
2
3
4
5
6
7
8
9
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.0.M1</version>
</plugin>
</plugins>
</build>

然后执行mvn jetty:run即可运行

使用jetty:run出现Timeout scan annotations的解决方法

现象mvn jetty:run之后,出现类似错误:

1
2
3
4
5
6
java.lang.Exception: Timeout scanning annotations
at org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:576)
at org.eclipse.jetty.annotations.AnnotationConfiguration.configure(AnnotationConfiguration.java:446)
at org.eclipse.jetty.webapp.WebAppContext.configure(WebAppContext.java:473)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1331)
......

但使用 mvn clean package,将打包后的war包放到tomcat下能正常运行

解决方法:增加jetty启动时对annotations的最长扫描时间

1
mvn jetty:run -Dorg.eclipse.jetty.annotations.maxWait=180


解决编码问题

问题1:多个plugin,例如maven-resources、maven-compile、maven-site等都需要设置encoding,解决方案:在pom.xml中设置一个属性:

1
2
3
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

详见:http://maven.apache.org/general.html#encoding-warning

问题2:单元测试时,控制台输出的中文乱码,原因是maven-surefire-plugin使用的编码和控制台的不一致导致(git/cygwin用户的是UTF-8, windows命令行用的是GBK),解决方案:

首先在pom.xml设置(假设统一使用UTF-8

1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<plugins>
......
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
</plugins>
</build>

然后在执行命令

1
mvn -Dfile.encoding=UTF-8 clean test

原则就是保证两者使用的编码一致


如何禁止cobertura:cobertura-integration-test运行

cobertura主要用于产生代码测试覆盖率的报告,可以配置到reporting节点,在site的生命周期中调用。但在site的生命周期中默认会先后调用cobertura:coberturacobertura:cobertura-integration-test两个goal,在运行cobertura:cobertura-integration-test的时候一般需要将cobertura.jar放到war包中,如果要实现该功能的话,要么把cobertura.jar加到依赖里,要么按照官网需要在很多地方做配置。考虑到集成测试生成的覆盖率没有太大意义,因此可以设置在site生命周期里不运行cobertura:cobertura-integration-test,设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<reporting>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<!-- 关键一步 -->
<reportSets>
<reportSet>
<reports>
<report>cobertura</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>


如何集成Jboss进行集成测试

思路主要来自:http://www.infoq.com/cn/news/2011/03/xxb-maven-5-integration-test/ Maven实战(五)——自动化Web应用集成测试

首先需要在测试前把应用服务器启动起来,并把war包部署到服务器上,这个主要是把jboss-as:startjboss-as:deploy这两个goal绑定到pre-integration-test阶段;另外在测试完之后要把服务器停掉,这个主要把jboss-as:shutdown绑定到post-integration-test阶段

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
<build>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.7.Final</version>
<executions>
<excution>
<id>jboss-start-deploy</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
<configuration>
<name>${project.artifactId}.${project.packaging}</name>
</configuration>
</excution>
<excution>
<id>jboss-shutdown</id>
<phase>post-integration-test</phase>
<goals>
<goal>shtudown</goal>
</goals>
</excution>
</executions>
</plugin>
</build>

另外,需要将集成测试的类命名为不含有Test(例如改为以*IT.java命名),否则在单元测试阶段会执行这些测试案例,之后需要将这些测试的执行绑定到integration-test阶段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<executions>
<excution>
<id>run-integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</excution>
</executions>
</plugin>
</build>


是否可以在setting.xml中配置distributeManager

答案是:否,只能在pom.xml中配置,但可以通过profile方式进行灵活配置


如何在每次构建出来的war包名中包含时间信息

增加如下属性:

1
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>

然后在包信息中利用${maven.build.timestamp}属性即可,但要注意该属性得到的时间是没有时区信息的


在MANIFEST.MF文件中增加自定义信息

配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifestEntries>
<Build-Number>${versionNumber}</Build-Number>
<Built-By>${user.name}</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>


如何将依赖包都打到jar里

方法:使用maven-assembly-plugin,主页为: http://maven.apache.org/plugins/maven-assembly-plugin/
pom.xml中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>xxx<id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor> <!-- 具体组装的描述文件 -->
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

根据上面配置的路径,在同一层目录新建assembly.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>xxx</id> <!-- 这个会附加到最终构件的文件名后面 -->
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>target/classes</directory> <!-- 将target/classes目录下的所有文件到打包到根目录下 -->
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory> <!-- 放到压缩包里的lib目录 -->
<scope>runtime</scope> <!-- 选取runtime范围的依赖包 -->
<useProjectArtifact>false</useProjectArtifact> <!-- 是否将构建出来的jar包也放到依赖里,默认是true -->
</dependencySet>
</dependencySets>
</assembly>

assembly.xml可用配置项详见: http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html

打包的最终结果是所有依赖包以及本身的包都会打到压缩包的lib目录中

如果只是想把项目依赖的class文件都打到jar包里,按以下配置即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>