You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'
    }
}

问题原因

  1. Shadow插件会自动创建默认的shadowJar任务,该任务默认生成带版本号的Jar包(如Translator-1.0.jar),你的配置中tasks.withType(ShadowJar).configureEach会对所有ShadowJar类型的任务生效,包括这个默认任务,导致它被执行并生成Jar。
  2. 手动覆盖了Java插件提供的jar和build任务,这种做法不仅多余,还会和插件自带的任务产生冲突:build原本是Java插件的生命周期任务,依赖一系列编译、打包流程,改成ShadowJar类型后会触发额外的Jar生成逻辑。
  3. 你定义的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:35:38