maven打包之assembly和shade对比

maven打包对比

java项目少不了第三方依赖,当使用mvn作为项目管理工具时,可以使用assembly和shade插件打包。

assembly和shade对比

assembly的优点
  1. thin jar 如果打fat jar,所有相关的类(含依赖)会被打进一个jar包,此时的问题是这个包除了比较大外,还失去了通过替换jar包更新程序的灵活性。assembly不会将依赖的jar包合并,仅仅是将它们放在一个压缩包中。
  2. 打包脚本,配置文件等 assembly除了打包依赖外,还能include用户定义的目录或文件。如一般项目都会在bin目录中放启动脚本等。
  3. 自定义依赖 assembly默认打包所有依赖的依赖,默认行为可能会打出很多jar包,可以手动include/exclude。

##### assembly的缺点

  1. 手动依赖修剪 assembly虽然可以通过定义include/exclude修剪依赖,但是需要用户明确自己的代码中用到了哪些,没用到哪些,否则如果该include没有include或被exclude了,那么很容易出No Class Found Exception

##### shade的优点

  1. shade支持修剪不必要的依赖 不像assembly需要用户自己进行修剪,shade能过通过字节码分析自动修剪掉不必要的依赖。
  2. 能够通过替换包名避免依赖冲突 如果一个项目中同时依赖了某个库的两个版本,比如spark程序中,自己的代码依赖okhttp 3, spark本身的代码依赖okhttp 2.此时除了重写自己的代码,更改依赖外,还可以通过shade解决依赖冲突。巧用maven-shade-plugin解决依赖冲突 - 简书
shade的缺点
  1. 不能打thin jar 即使shade能够修剪依赖,最终也只能将所有类打到一个jar包中。
  2. 无法打包脚本,配置文件等

assembly打包

添加assembly插件

项目pom.xml的bulid标签的plugins中添加如下

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>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
          <!--避免打出的包含id,本例中为bin-->
          <appendAssemblyId>false</appendAssemblyId>
          <descriptors>
              <descriptor>assembly.xml</descriptor>
          </descriptors>
      </configuration>
      <executions>
          <execution>
              <id>bin</id>
              <phase>package</phase>
              <goals>
                  <goal>single</goal>
              </goals>
          </execution>
      </executions>
  </plugin>
</plugins>
</build>
添加assembly.xml到项目根目录

如下配置,最终会将项目打包为一个tar.gz包,压缩文件的lib目录含项目本身的包及依赖包,以及resources目录下的文件,压缩文件的根目录下会含有所有项目目录deploy中的文件。

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
<assembly>
  <id>bin</id>
  <formats>
      <format>tar.gz</format>
  </formats>
  <dependencySets>
      <dependencySet>
          <outputDirectory>lib</outputDirectory>
      </dependencySet>
  </dependencySets>
  <fileSets>
      <fileSet>
          <directory>src/main/resources</directory>
          <outputDirectory>lib</outputDirectory>
      </fileSet>
      <fileSet>
          <directory>deploy</directory>
          <outputDirectory>/</outputDirectory>
      </fileSet>
  </fileSets>
  <files>
      <!--<file>
          <source>run.sh</source>
          <outputDirectory>/</outputDirectory>
      </file>-->
  </files>
</assembly>

shade打包

项目pom.xml文件build部分含shade插件即可。

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
    <build>
      <plugins>
          <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>3.1.1</version>
          <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                      <goal>shade</goal>
                  </goals>
                  <configuration>
                      <filters>
                          <filter>
                              <!-- Do not copy the signatures in the META-INF folder.
                              Otherwise, this might cause SecurityExceptions when using the JAR. -->
                              <artifact>*:*</artifact>
                              <excludes>
                                  <exclude>META-INF/*.SF</exclude>
                                  <exclude>META-INF/*.DSA</exclude>
                                  <exclude>META-INF/*.RSA</exclude>
                              </excludes>
                          </filter>
                      </filters>
                      <!--<transformers>
                          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                              <mainClass>demo.SocketWindowWC</mainClass>
                          </transformer>
                      </transformers>-->
                  </configuration>
              </execution>
          </executions>
      </plugin>
      </plugins>
  </build>