Gradle构建生成双Jar包:如何仅保留指定Fat Jar?
Gradle构建生成多余Jar包的问题解决
问题描述
执行以下Gradle构建脚本时,build/libs目录下会同时生成Translator.jar和Translator-1.0.jar两个Jar包,需求是仅保留Translator.jar这个Fat Jar:
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id 'java' id 'com.github.johnrengelman.shadow' version '5.2.0' } group = 'translator' version = '1.0' sourceCompatibility = '1.8' targetCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.jetbrains:annotations:24.0.1' compile group: 'org.json', name: 'json', version: '20230227' } compileJava { options.encoding = 'UTF-8' } task jar(overwrite: true, type: ShadowJar) { archiveName 'Translator.jar' from sourceSets.main.output } task build(overwrite: true, type: ShadowJar) { archiveName 'Translator.jar' from sourceSets.main.output } tasks.register('relocateShadowJar', ConfigureShadowRelocation) { target = tasks.shadowJar } tasks.withType(ShadowJar).configureEach { dependsOn relocateShadowJar configurations = [ project.configurations.shadow ] from { project.configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } dependencies { exclude 'META-INF/*.SF' exclude 'META-INF/*.DSA' exclude 'META-INF/*.RSA' exclude 'META-INF/*.MF' } }
问题原因
- Shadow插件会自动创建默认的
shadowJar任务,该任务默认生成带版本号的Jar包(如Translator-1.0.jar),你的配置中tasks.withType(ShadowJar).configureEach会对所有ShadowJar类型的任务生效,包括这个默认任务,导致它被执行并生成Jar。 - 手动覆盖了Java插件提供的
jar和build任务,这种做法不仅多余,还会和插件自带的任务产生冲突:build原本是Java插件的生命周期任务,依赖一系列编译、打包流程,改成ShadowJar类型后会触发额外的Jar生成逻辑。 - 你定义的
relocateShadowJar任务目标是默认的shadowJar,这会强制该默认任务执行,进而生成带版本的Jar。
解决方案
核心思路
- 直接配置插件默认的
shadowJar任务,指定输出Jar名称为Translator.jar。 - 禁用Java插件默认的
jar任务,避免生成瘦Jar。 - 让
build生命周期任务依赖shadowJar,确保执行build时只生成Fat Jar。 - 调整
relocateShadowJar任务的配置,确保它作用于正确的任务。
修改后的完整脚本
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id 'java' id 'com.github.johnrengelman.shadow' version '5.2.0' } group = 'translator' version = '1.0' sourceCompatibility = '1.8' targetCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.jetbrains:annotations:24.0.1' implementation 'org.json:json:20230227' // 统一用implementation替代已废弃的compile } compileJava { options.encoding = 'UTF-8' } // 配置默认shadowJar任务,指定输出名称 shadowJar { archiveName = 'Translator.jar' // 配置依赖排除规则 dependencies { exclude 'META-INF/*.SF' exclude 'META-INF/*.DSA' exclude 'META-INF/*.RSA' exclude 'META-INF/*.MF' } // 配置构建内容 configurations = [project.configurations.shadow] from { project.configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } } } // 禁用Java插件默认的jar任务,避免生成瘦Jar jar { enabled = false } // 让build任务依赖shadowJar,执行build时自动生成Fat Jar build.dependsOn(shadowJar) // 配置重定位任务,目标为shadowJar tasks.register('relocateShadowJar', ConfigureShadowRelocation) { target = shadowJar } // 让shadowJar依赖重定位任务 shadowJar.dependsOn(relocateShadowJar)
关键调整说明
- 移除了手动覆盖的
jar和build任务,改用配置默认任务的方式,避免任务冲突。 - 将
compile依赖改为implementation(Gradle中compile已被废弃,推荐使用implementation)。 - 禁用Java插件默认的
jar任务,彻底阻止瘦Jar生成。 - 把原来
tasks.withType(ShadowJar).configureEach中的配置直接移到shadowJar任务里,确保只作用于目标Fat Jar任务。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

