三种 maven 打包插件使用

转自maven-jar-plugin & maven-assembly-plugin & maven-shade-plugin

说一说 maven-jar-pluginmaven-assembly-pluginmaven-shade-plugin 的使用,和他们之间的区别。

maven-jar-plugin

首先,需要配置这个plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>    
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>cn.dubby.maven.jar.plugin.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

编写启动类:

1
2
3
4
5
public static void main(String[] args) {    
System.out.println("Hello, this is a application packaged by maven-jar-plugin");
LocalDateTime localDateTime = new LocalDateTime();
System.out.println(localDateTime);
}

启动:

1
➜  target git:(master) ✗ java -jar maven-jar-plugin-1.0-SNAPSHOT.jarHello, this is a application packaged by maven-jar-plugin

但是,如果加上一个依赖呢?

我们加上 joda-time 的依赖:

1
2
3
4
5
6
7
8
<dependencies>    
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.9</version>
</dependency>
</dependencies>

修改启动类:

1
2
3
4
5
public static void main(String[] args) {    
System.out.println("Hello, this is a application packaged by maven-jar-plugin");
LocalDateTime localDateTime = new LocalDateTime();
System.out.println(localDateTime);
}

再运行:

1
2
3
4
5
6
7
8
9
10
➜  target git:(master) ✗ java -jar maven-jar-plugin-1.0-SNAPSHOT.jar
Hello, this is a application packaged by maven-jar-plugin
Exception in thread "main" java.lang.NoClassDefFoundError: org/joda/time/LocalDateTime
at cn.dubby.maven.jar.plugin.Main.main(Main.java:13)
Caused by: java.lang.ClassNotFoundException: org.joda.time.LocalDateTime
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

发现我们增加的依赖并没有找到,怎么办呢?

请注意观察我们上面配置 maven-jar-plugin 时的另外两个配置项:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>    
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>cn.dubby.maven.jar.plugin.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

addClasspathclasspathPrefix 表明会把 lib 下的 jar 作为第三方依赖加入 package 里,所以我们需要把依赖拷贝到 lib 目录下,我们可以使用 maven-dependency-plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<plugin>    
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

这样我们重新打包再运行:

1
2
➜  target git:(master) ✗ java -jar maven-jar-plugin-1.0-SNAPSHOT.jar
Hello, this is a application packaged by maven-jar-plugin

去target目录下也可以发现多了个lib目录。

maven-assembly-plugin

先配置plugin:

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
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>cn.dubby.maven.assembly.plugin.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

启动类同上:

1
2
3
4
5
public static void main(String[] args) {
System.out.println("Hello, this is a application packaged by maven-assembly-plugin");
LocalDateTime localDateTime = new LocalDateTime();
System.out.println(localDateTime);
}

打包运行结果:

1
2
➜  target git:(master) ✗ java -jar maven-assembly-plugin-1.0-SNAPSHOT-jar-with-dependencies.jar
Hello, this is a application packaged by maven-assembly-plugin

maven-shade-plugin

配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- maven-shade-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>cn.dubby.maven.shade.plugin.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

启动类同上:

1
2
3
4
5
public static void main(String[] args) {
System.out.println("Hello, this is a application packaged by maven-shade-plugin");
LocalDateTime localDateTime = new LocalDateTime();
System.out.println(localDateTime);
}

结果:

1
2
➜  target git:(master) ✗ java -jar maven-shade-plugin-1.0-SNAPSHOT.jar
Hello, this is a application packaged by maven-shade-plugin

package比较

1
2
3
-rw-r--r--  1 teeyoung  staff   622K  1 22 15:43 maven-assembly-plugin-1.0-SNAPSHOT-jar-with-dependencies.jar
-rw-r--r-- 1 teeyoung staff 3.1K 1 22 14:47 maven-jar-plugin-1.0-SNAPSHOT.jar
-rw-r--r-- 1 teeyoung staff 622K 1 22 15:42 maven-shade-plugin-1.0-SNAPSHOT.jar