Maven 打包Jar 插件

Maven可以使用mvn package指令对项目进行打包。Maven 提供的打包插件一共有三种,每种打包方式都有自己的应用场景。

在Java中,如果使用

1
java -jar xxx.jar

来执行运行jar文件经常会出现没有设置main-class,ClassNotFoundException(找不到依赖包)等错误。

要想jar包通过java -jar xxx.jar运行,必须满足:

  1. 在jar包中的META-INF/MANIFEST.MF中指定Main-class,确定程序入口在哪里
  2. 将所有需要加载的依赖包通过-classpath导入

使用maven可以通过如下几个插件来生成能直接运行的jar包。

插件名 功能
maven-jar-plugin maven默认的打包插件,用来创建project jar
maven-shade-plugin 用来打可执行包,executable jar
maven-assembly-plugin 支持定制化打包方式,例如apache项目的打包方式

参考https://blog.csdn.net/xiao__gui/article/details/47341385

方法一:使用maven-jar-plugin和maven-dependency-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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<build>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxg.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>
  • 首先要将所需要的依赖包包含进这个tag。如果没有吧依赖包加进来那么一定会产生编译错误。

  • maven-jar-plugin用于生成META-INF/MANIFEST.MF文件的部分内容

    com.xxx.Main 指定了MANIFEST.MF中的Main-Class
    true会在MANIFEST.MF加上Class-Path项并配置依赖包,
    lib/指定依赖包所在的目录。

  • maven-dependency-plugin插件用于将依赖包拷贝到${project.build.directory}/lib指定的位置,即lib目录下。注意,如果不包含这个插件的话,mvn还是会先从中央仓库下载相关的依赖包,但是不会将依赖包表现在你的生成文件中,也就是你并不能实际的找到这个依赖包。这样某种程度影响不大。

配置完成后,通过mvn package指令打包,会在target目录下生成jar包,并将依赖包拷贝到目录/target/lib/下。

方法二:使用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

<build>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>com.xxg.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>

打包方式:

1
mvn package assembly:single

打包后会在target目录下生成一个xxx-jar-with-dependencies.jar文件,这个文件不但包含自己项目下的所有代码和资源,而且包含了所有依赖包的内容。可以复制到任何地方直接通过java -jar 来运行。

当然也可以通过 mvn package来打包,无需assembly:single,而且需要加上一些额外配置:

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
<build>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>com.xxg.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

</plugins>
</build>

其中package, single表示在执行package命令的时候执行assembly:single。

不过,如果项目中用到Spring Framework,用这种方式打出来的包运行时会出错。可以使用下边的方法三进行处理。

方法三:使用maven-shade-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
23
24
25
26
<build>
<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.xxg.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>

配置完成后,执行mvn package进行打包。在target目录下会生成两个jar包。和maven-assembly-plugin一样,生成的jar文件包含了所有的依赖,可以直接运行。