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

Java FatJar抛出NoClassDefFoundError问题求助

问题解决:自定义Gradle FatJar任务导致客户端类找不到的问题

核心解决方案

修改你的buildJar任务配置,确保自己的类被正确打包,并避免依赖库的签名文件冲突:

task buildJar(type: Jar) {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE

    manifest {
        attributes 'Implementation-Title': 'Gradle Jar',
                   'Implementation-Version': version
    }
    baseName = "testlibrary"
    
    // 明确添加自身项目编译后的类和资源文件
    from sourceSets.main.output
    
    // 添加依赖库内容,同时排除签名文件避免Jar损坏
    from {
        configurations.compileClasspath.collect {
            it.isDirectory() ? it : zipTree(it).matching {
                exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA'
            }
        }
    }
}

问题原因分析

  1. 原任务的配置顺序与可靠性问题
    你原任务中先添加依赖库内容,再通过with jar合并默认Jar任务配置。虽然理论上会包含自身类,但duplicatesStrategy = DuplicatesStrategy.EXCLUDE可能在依赖库存在同名空目录时,意外排除自身类。直接使用sourceSets.main.output指定打包自身类,逻辑更清晰可靠。

  2. 未处理依赖库的签名文件
    多数第三方Jar包含数字签名文件(META-INF下的.SF/.DSA/.RSA),打包FatJar时保留这些文件会导致Jar类加载时出现验证错误,间接引发NoClassDefFoundError。

  3. 依赖配置的优化点
    原任务使用compileClasspath是可行的,但如果要确保只打包运行时必需的依赖,可以替换为runtimeClasspath(它不包含compileOnly类型的依赖,更适合FatJar场景)。

验证步骤

  1. 执行命令重新生成Jar:./gradlew clean buildJar
  2. 解压生成的Jar,确认com/test/lib/factory/TestFactory.class存在于正确的包路径下
  3. 将新Jar替换客户端项目libs目录中的旧Jar,重新执行客户端代码

另外,如果你想简化FatJar构建流程,也可以使用Gradle官方推荐的shadow插件(id 'com.github.johnrengelman.shadow' version '7.1.2'),它能自动处理依赖合并、签名文件排除等问题,避免手动配置的疏漏。

内容的提问来源于stack exchange,提问作者user

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:17:33