使用Gradle-7.5.1创建Jar时如何移除无关文件与依赖?
解决Gradle打包Jar包含无关内容的问题
问题原因
你自定义的fatJar任务中,这行代码是导致Jar混入大量无关内容的核心原因:
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
它会将所有runtimeClasspath下的依赖包(比如你引入的slf4j-api以及其他未列出的依赖)解压后全部打包进Jar,那些assets、javax、corejava等目录都是来自这些第三方依赖。
解决方案
你需要的是仅包含自身代码和Manifest的Jar,不需要打包依赖,因此可以通过以下两种方式实现:
方式1:直接修改默认jar任务(推荐)
Java插件默认提供的jar任务,本身就只会打包你的源码编译后的class文件和Manifest,只需调整它的配置即可满足你的命名和Manifest需求:
apply plugin: 'java' apply plugin: 'application' version = '1.0' sourceSets { main { java { srcDirs = ['src'] } } } // 调整默认jar任务的配置 jar { manifest { attributes 'Manifest-Version': version, // 如果不需要Class-Path属性可以直接删除这行 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') } baseName = 'MyProj' // 生成的Jar名称会是MyProj-1.0.jar } repositories { mavenCentral() } dependencies { implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' // 补充你其他的依赖 }
方式2:修改自定义任务(移除依赖打包逻辑)
如果你坚持要使用自定义任务名称,只需移除引入依赖内容的代码即可:
apply plugin: 'java' apply plugin: 'application' version = '1.0' sourceSets { main { java { srcDirs = ['src'] } } } // 建议改名避免和"fatJar(包含所有依赖的Jar)"的含义混淆 task myJar(type: Jar) { manifest { attributes 'Manifest-Version': version, 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ') } baseName = 'MyProj' with jar // 这行已经包含了你的编译代码和默认Manifest配置 // 移除下面这行依赖打包逻辑 // from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } } repositories { mavenCentral() } dependencies { implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' // 补充你其他的依赖 }
执行对应任务(默认jar任务执行./gradlew jar,自定义任务执行./gradlew myJar)后,生成的Jar就只会包含META-INF目录(含Manifest.MF)和你自己的代码目录(比如com)了。
内容的提问来源于stack exchange,提问作者5122014009
相关产品推荐
相关产品推荐

