如何使用Gradle ShadowJar创建不解压类文件的Jar of Jars?
创建无需解压内部Jar的Jar of Jars(Gradle实现)
我来帮你解决这个问题!你之前的配置用了zipTree(),这会把每个依赖Jar都解压后再打包,所以最终生成的Jar里都是类文件和目录,而不是你想要的嵌套Jar。下面给你两种可行的实现方案:
方案一:原生Gradle Jar任务实现
直接修改你的jar任务配置,跳过解压步骤,把依赖Jar直接打包进去,同时配置MANIFEST让JVM能识别这些内部Jar:
jar { // 直接将运行时依赖的Jar文件打包进最终Jar,不解压任何内容 from { configurations.runtimeClasspath.collect { it } } // 如果你用的是Gradle 4之前的版本,替换成configurations.compile即可 // 配置MANIFEST.MF文件,关键是设置主类和类路径 manifest { attributes( // 替换成你的项目主类全路径,如果没有主类可以去掉这一行 'Main-Class': 'com.yourpackage.YourMainClass', // 生成Class-Path属性,列出所有内部Jar的相对路径 'Class-Path': configurations.runtimeClasspath.files.collect { it.name }.join(' ') ) } }
如果想把内部Jar统一放到lib子目录(更整洁),可以调整成这样:
jar { // 将依赖Jar打包到最终Jar的lib目录下 into('lib') { from configurations.runtimeClasspath } manifest { attributes( 'Main-Class': 'com.yourpackage.YourMainClass', // 类路径要对应lib目录下的Jar文件 'Class-Path': configurations.runtimeClasspath.files.collect { "lib/${it.name}" }.join(' ') ) } }
方案二:用ShadowJar插件实现Jar of Jars模式
如果你还是想用ShadowJar,其实它也支持不解压依赖Jar的打包方式,只要调整插件配置,关闭解压合并的逻辑:
plugins { id 'com.github.johnrengelman.shadow' version '7.1.2' // 建议使用最新稳定版本 } shadowJar { // 关闭服务文件合并,避免自动解压依赖Jar mergeServiceFiles = false // 将依赖Jar打包到lib子目录 into('lib') { from configurations.runtimeClasspath } // 配置MANIFEST,和原生Jar任务逻辑一致 manifest { attributes( 'Main-Class': 'com.yourpackage.YourMainClass', 'Class-Path': configurations.runtimeClasspath.files.collect { "lib/${it.name}" }.join(' ') ) } }
注意事项
- 运行这种Jar of Jars时,直接用
java -jar your-final-jar-name.jar即可,JVM会通过MANIFEST里的Class-Path属性找到内部的Jar文件,不需要手动解压最终Jar。 - 确保
runtimeClasspath(或compile)配置正确,包含了你需要打包的所有依赖Jar。
内容的提问来源于stack exchange,提问作者Badri
相关产品推荐
相关产品推荐

