Maven 打包包含第三方依赖:Assembly 与 Shade 插件详解
在 Java 项目部署时,常常需要将第三方依赖一并打包,生成可直接运行的 Jar 包(无需用户手动下载依赖)。Maven 提供了 maven-assembly-plugin
和 maven-shade-plugin
两个核心插件实现这一需求,本文将详细介绍两者的配置与差异。
为什么需要包含第三方依赖?
- 独立运行:生成的 Jar 包可直接通过
java -jar
命令运行,无需依赖外部 Maven 仓库。 - 环境一致性:避免因依赖版本差异导致的 “本地能跑,线上报错” 问题。
- 简化部署:只需传输一个 Jar 包,无需额外配置依赖路径。
Assembly 插件:灵活的打包方案
maven-assembly-plugin
是 Maven 官方插件,支持多种打包格式(如 Jar、Zip、Tar),并可通过描述符(descriptor)自定义打包内容。
核心配置(包含所有依赖的 Jar 包)
1 | <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 | <descriptors> |
Shade 插件:解决依赖冲突的高级方案
maven-shade-plugin
是 Apache 提供的另一个打包插件,相比 Assembly 插件,它支持依赖重命名和冲突解决,适合复杂项目。
基础配置(包含依赖并可执行)
1 | <build> |
执行与效果
- 执行命令:
mvn clean package
- 生成的 Jar 包位于
target/
目录,默认覆盖原 Jar 包(或按finalName
命名,如demo-1.0-SNAPSHOT-shaded.jar
)。 - 包内结构:依赖类会被合并到 Jar 中,支持通过配置排除或重命名类。
高级功能:解决依赖冲突
当多个依赖包含同名类时,Shade 插件可通过 Relocation 重命名包路径,避免冲突:
1 | <configuration> |
此外,还可排除不需要的依赖:
1 | <configuration> |
Assembly 与 Shade 插件的对比
特性 | Assembly 插件 | Shade 插件 |
---|---|---|
依赖处理 | 简单合并,不处理同名类冲突 | 支持重命名类、排除冲突依赖 |
可执行 Jar | 支持(需配置 manifest) | 支持(通过 transformer 配置) |
打包格式 | 支持 Jar、Zip、Tar 等多种格式 | 主要生成 Jar 格式 |
适用场景 | 简单项目,需包含所有依赖 | 复杂项目,存在依赖冲突或需定制化打包 |
输出 Jar 大小 | 较大(包含所有依赖,可能有冗余) | 可通过过滤减小体积 |
使用建议
- 简单项目:优先选择
assembly
插件,配置简单,满足基本需求。 - 复杂项目:使用
shade
插件,解决依赖冲突,增强打包灵活性。 - 可执行 Jar:两者均需配置
mainClass
,确保能通过java -jar
直接运行。 - 版本控制:始终指定插件的具体版本(如
3.3.0
),避免因版本差异导致的问题。
v1.3.10