Gradle 6.0构建Uber Jar成功,运行时报java.lang.ClassNotFoundException如何解决
问题原因
你自定义的Uber Jar打包逻辑未处理第三方依赖内置的签名校验文件、重复资源,JVM运行时会校验Jar包完整性,发现签名不匹配后会拒绝加载对应类,即使类路径和Main-Class配置完全正确也会抛出类找不到异常。
修复方案
方案1:修改现有自定义uberJar任务
在原有uberJar配置中增加签名文件排除、重复资源处理规则,修改后的配置如下:
task uberJar(type: Jar) { manifest { attributes 'Main-Class': 'com.noths.runner.Runner' } archiveClassifier = 'uber' from sourceSets.main.output dependsOn configurations.runtimeClasspath from { configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } } // 排除第三方依赖的签名文件,避免校验失败 exclude 'META-INF/*.SF' exclude 'META-INF/*.DSA' exclude 'META-INF/*.RSA' exclude 'META-INF/INDEX.LIST' // 处理重复文件冲突 duplicatesStrategy = DuplicatesStrategy.EXCLUDE }
修改后重新执行gradle clean uberJar即可。
方案2:使用Shadow插件(更稳定)
你配置注释中已经提到了Shadow插件,直接引入该插件可以自动处理所有Uber Jar打包的适配问题,无需手动处理资源冲突:
- 修改plugins块引入适配Gradle 6.0的Shadow插件:
plugins { id 'java' id 'com.github.johnrengelman.shadow' version '6.1.0' }
- 增加Shadow插件的主类配置,删除原有自定义uberJar任务:
shadowJar { manifest { attributes 'Main-Class': 'com.noths.runner.Runner' } archiveClassifier = 'uber' }
- 执行
gradle clean shadowJar即可生成可正常运行的Uber Jar包。
额外检查项
确认com.noths.runner.Runner类满足以下条件:
- 类修饰符为
public - 存在
public static void main(String[] args)方法定义
内容的提问来源于stack exchange,提问作者SRJ
相关产品推荐
相关产品推荐

