Maven Shade不解压依赖打包Uber Jar的技术问询
不解压依赖打包可执行Jar的优缺点及可用Maven插件
一、不解压依赖打包方式的优缺点
优点
- 彻底避免文件冲突:你遇到的
META-INF/MANIFEST.MF、module-info.class重叠问题会直接消失,每个依赖保持独立Jar结构,不会互相覆盖 - 打包速度更快:省去了解压所有依赖再重新合并打包的IO操作,构建效率明显提升
- 结构直观清晰:最终Jar里能直接看到项目自身代码和各个依赖Jar,排查依赖版本、冲突问题时定位更方便
- 保留依赖签名:如果依赖Jar带有签名校验,不解压打包不会破坏签名,避免运行时出现签名验证失败的问题
缺点
- 类加载复杂度提高:需要依赖自定义类加载器或者JDK的Jar-in-Jar机制来加载嵌套Jar,不像Shade打包的Jar能用系统类加载器直接加载所有类
- 最终Jar体积略大:每个依赖Jar自带的元数据文件会保留,相比解压合并后的Jar会多一些冗余内容
- 工具兼容性受限:部分代码分析、调试工具对嵌套Jar的支持不够友好,比如某些代码覆盖率工具、反编译工具可能无法直接解析嵌套Jar里的类
二、除Assembly外的现成Maven插件
1. Spring Boot Maven Plugin
虽然主打Spring Boot项目,但普通Java项目也能用来构建带嵌套依赖的可执行Jar。它会自动把依赖打包到BOOT-INF/lib目录,生成正确的MANIFEST.MF,还自带类加载器处理嵌套Jar的加载逻辑。
核心配置示例:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <mainClass>com.yourpackage.YourMainClass</mainClass> <layout>JAR</layout> </configuration> </plugin>
2. Maven Jar Plugin + Maven Dependency Plugin
这种方式不算把依赖打包进Jar,而是将依赖Jar复制到Jar所在的同级目录,通过Jar的MANIFEST.MF里的Class-Path属性指定依赖位置,同样实现了不解压的依赖管理。
配置示例片段:
<!-- 生成带主类和Class-Path的Jar --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <mainClass>com.yourpackage.YourMainClass</mainClass> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> </archive> </configuration> </plugin> <!-- 复制依赖到lib目录 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.6.0</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>
3. OneJar Maven Plugin
专门为构建包含嵌套依赖的可执行Jar设计,会把项目代码和所有依赖Jar打包进一个Jar,内部通过自定义类加载器加载嵌套Jar,配置简单,适合普通Java项目。
核心配置示例:
<plugin> <groupId>com.jolira</groupId> <artifactId>onejar-maven-plugin</artifactId> <version>1.4.4</version> <executions> <execution> <goals> <goal>one-jar</goal> </goals> </execution> </executions> <configuration> <mainClass>com.yourpackage.YourMainClass</mainClass> </configuration> </plugin>
内容的提问来源于stack exchange,提问作者SinaMobasheri
相关产品推荐
相关产品推荐

