0%

maven打包包含第三方依赖

Maven 打包包含第三方依赖:Assembly 与 Shade 插件详解

在 Java 项目部署时,常常需要将第三方依赖一并打包,生成可直接运行的 Jar 包(无需用户手动下载依赖)。Maven 提供了 maven-assembly-pluginmaven-shade-plugin 两个核心插件实现这一需求,本文将详细介绍两者的配置与差异。

为什么需要包含第三方依赖?

  • 独立运行:生成的 Jar 包可直接通过 java -jar 命令运行,无需依赖外部 Maven 仓库。
  • 环境一致性:避免因依赖版本差异导致的 “本地能跑,线上报错” 问题。
  • 简化部署:只需传输一个 Jar 包,无需额外配置依赖路径。

Assembly 插件:灵活的打包方案

maven-assembly-plugin 是 Maven 官方插件,支持多种打包格式(如 Jar、Zip、Tar),并可通过描述符(descriptor)自定义打包内容。

核心配置(包含所有依赖的 Jar 包)

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
38
39
40
41
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version> <!-- 推荐使用最新版本 -->
<configuration>
<!--
描述符
1、bin - 将jar包打zip包
2、jar-with-denpendencies - 带有依赖的jar包
3、project - 将工程源代码打包
4、src - 将工程src目录下的源代码打包
-->
<!-- 描述符:指定打包类型,jar-with-dependencies 表示包含所有依赖 -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>

<!-- 配置可执行 Jar 的入口类(可选) -->
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.zhanghe.Main</mainClass> <!-- 替换为你的主类全路径 -->
</manifest>
</archive>
</configuration>

<!-- 绑定到 package 阶段,执行 mvn package 时自动打包 -->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal> <!-- 单一次打包 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

执行与效果

  • 执行命令:mvn clean package
  • 生成的 Jar 包位于 target/ 目录,命名格式为 [artifactId]-[version]-jar-with-dependencies.jar(如 demo-1.0-SNAPSHOT-jar-with-dependencies.jar)。
  • 包内结构:包含项目自身的类和所有第三方依赖的类(平铺在 BOOT-INF/classes 或根目录下)。

其他常用描述符

除了 jar-with-dependencies,Assembly 插件还支持多种预设描述符:

描述符 作用
bin 打包成 Zip 格式,包含 Jar 包和脚本
project 打包项目源码和资源(用于分发源码)
src 仅打包 src 目录下的源代码

如需自定义打包规则(如排除某些依赖、添加配置文件),可创建自定义描述符文件(如 src/main/assembly/assembly.xml),并在 <configuration> 中指定:

1
2
3
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>

Shade 插件:解决依赖冲突的高级方案

maven-shade-plugin 是 Apache 提供的另一个打包插件,相比 Assembly 插件,它支持依赖重命名冲突解决,适合复杂项目。

基础配置(包含依赖并可执行)

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
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version> <!-- 推荐最新版本 -->
<executions>
<execution>
<phase>package</phase> <!-- 绑定到 package 阶段 -->
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- 配置可执行入口类 -->
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.zhanghe.Main</mainClass> <!-- 主类全路径 -->
</transformer>
</transformers>

<!-- 可选:重命名输出 Jar 包(默认覆盖原 Jar) -->
<finalName>${project.artifactId}-${project.version}-shaded</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

执行与效果

  • 执行命令:mvn clean package
  • 生成的 Jar 包位于 target/ 目录,默认覆盖原 Jar 包(或按 finalName 命名,如 demo-1.0-SNAPSHOT-shaded.jar)。
  • 包内结构:依赖类会被合并到 Jar 中,支持通过配置排除或重命名类。

高级功能:解决依赖冲突

当多个依赖包含同名类时,Shade 插件可通过 Relocation 重命名包路径,避免冲突:

1
2
3
4
5
6
7
8
9
<configuration>
<relocations>
<!-- 将 com.google.gson 重命名为 shaded.com.google.gson -->
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>shaded.com.google.gson</shadedPattern>
</relocation>
</relocations>
</configuration>

此外,还可排除不需要的依赖:

1
2
3
4
5
6
7
8
9
10
11
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude> <!-- 排除签名文件 -->
<exclude>META-INF/*.DSA</exclude>
</excludes>
</filter>
</filters>
</configuration>

Assembly 与 Shade 插件的对比

特性 Assembly 插件 Shade 插件
依赖处理 简单合并,不处理同名类冲突 支持重命名类、排除冲突依赖
可执行 Jar 支持(需配置 manifest) 支持(通过 transformer 配置)
打包格式 支持 Jar、Zip、Tar 等多种格式 主要生成 Jar 格式
适用场景 简单项目,需包含所有依赖 复杂项目,存在依赖冲突或需定制化打包
输出 Jar 大小 较大(包含所有依赖,可能有冗余) 可通过过滤减小体积

使用建议

  1. 简单项目:优先选择 assembly 插件,配置简单,满足基本需求。
  2. 复杂项目:使用 shade 插件,解决依赖冲突,增强打包灵活性。
  3. 可执行 Jar:两者均需配置 mainClass,确保能通过 java -jar 直接运行。
  4. 版本控制:始终指定插件的具体版本(如 3.3.0),避免因版本差异导致的问题。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10