Maven Tips

Nexus

使用本地代理仓库

  • Nexus配置好后会默认有一个Maven Central仓库的Proxy,将自己的项目配置成使用代理

    1
    2
    3
    4
    5
    6
    7
    <repositories>
    <repository>
    <id>central</id>
    <name>Central</name>
    <url>http://foo.bar/content/repositories/central</url>
    </repository>
    </repositories>
  • 将插件仓库也配置成使用本地代理

    1
    2
    3
    4
    5
    6
    7
    <pluginRepositories>
    <pluginRepository>
    <id>central</id>
    <name>Central</name>
    <url>http://foo.bar/content/repositories/central</url>
    </pluginRepository>
    </pluginRepositories>

调整Nexus缓存时间

由于国内访问Maven仓库很卡,容易发生网络故障导致Nexus缓存了未找到记录,可在Nexus后台将对应仓库的Not Found Cache TTL改成一个较短的值(例如5分钟)

为不同的开发环境创建不同的仓库

通常一个项目在不同的环境下存在不同的版本,本文创建dev、qa、production三个仓库并演示如何通过变量来选择使用哪个仓库

使用变量

使用不同的profile定制变量

以下配置声明了dev、qa、production三个profile,并分别定义了branch和skipTest两个变量,且将dev置为默认激活的profile:

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
<profiles>
<profile>
<id>dev</id>
<properties>
<branch>dev</branch>
<skipTest>false</skipTest>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>qa</id>
<properties>
<branch>qa</branch>
<skipTest>true</skipTest>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<branch>production</branch>
<skipTest>true</skipTest>
</properties>
</profile>
</profiles>
命令行可通过-P参数来指定使用不同的profile,例如:
1
mvn -Pqa install

通过变量声明仓库

在Central仓库基础上加入

1
2
3
4
5
6
7
8
9
10
11
12
<repositories>
<repository>
<id>foobar-${branch}</id>
<name>foobar ${branch}</name>
<url>http://foo.bar/content/repositories/${branch}</url>
</repository>
<repository>
<id>central</id>
<name>Central</name>
<url>http://foo.bar/content/repositories/central</url>
</repository>
</repositories>

禁用仓库中Snapshot版本的唯一版本号

1
2
3
4
5
6
7
8
9
10
11
<repository>
<id>foobar</id>
<name>foobar</name>
<url>http://foo.bar/content/repositories/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>

发布

配置deploy仓库

以配置snapshotRepository为例:

1
2
3
4
5
6
7
<distributionManagement>
<snapshotRepository>
<id>${branch}</id>
<name>${branch} Snapshot Repository</name>
<url>http://foo.bar/content/repositories/${branch}</url>
</snapshotRepository>
</distributionManagement>

配置deploy账号

编辑文件:

1
vim ~/.m2/settings.xml
文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>production</id>
<username>deployment</username>
<password>deployment</password>
</server>
<server>
<id>qa</id>
<username>deployment</username>
<password>deployment</password>
</server>
<server>
<id>dev</id>
<username>deployment</username>
<password>deployment</password>
</server>
</servers>
</settings>

常规发布

通过前两处配置,已经可以正常发布:

1
mvn deploy

跳过发布

通常对于J2EE的WAR项目,只需要编译打包,而不需要将WAR文件发布到仓库中,通过配置maven-deploy-plugin跳过发布环节:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
<directory>${project.basedir}/target</directory>
<finalName>${project.artifactId}-${project.version}</finalName>
</build>

打包额外的jar

通过maven-jar-plugin可以在项目中打包出更多的自定义jar包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>foobar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<includes>
<include>**/foo/bar/**</include>
</includes>
<finalName>${project.artifactId}-${project.version}-foobar</finalName>
</configuration>
</execution>
</executions>
</plugin>
可通过配置多个execution并为其指定不同的id来打出更多的jar **注意:此方式打出的jar不会在deploy时发布到仓库中,而通过classfier方式打出的jar会发布,请注意此区别**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>foobar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>foobar</classfier>
<includes>
<include>**/foo/bar/**</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
以上两种方式在编译期都可以做到在target目录输出jar包的效果

发布额外打包的jar并指定自定义POM

以下配置将当前构建跳过发布,并打包额外的jar,然后为这个jar指定自定义的POM信息后上传至指定仓库:

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
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>foobar</id>
<phase>deploy</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<packaging>jar</packaging>
<generatePom>true</generatePom>
<repositoryId>${branch}</repositoryId>
<url>${project.distributionManagement.snapshotRepository.url}</url>
<groupId>foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>${project.version}</version>
<file>${project.build.directory}/${project.artifactId}-${project.version}-foobar.jar</file>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
<directory>${project.basedir}/target</directory>
<finalName>${project.artifactId}-${project.version}</finalName>
</build>

包含空目录

Maven构建时会自动忽略空目录,以下插件配置可将空目录保留:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<includeEmptyDirectories>true</includeEmptyDirectories>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<configuration>
<includeEmptyDirs>true</includeEmptyDirs>
</configuration>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
<directory>${project.basedir}/target</directory>
<finalName>${project.artifactId}-${project.version}</finalName>
</build>