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

在子目录创建Jar文件时出现NoClassDefFoundError及类加载失败问题

解决子目录打包Jar时BouncyCastleProvider加载失败的问题

太懂这种离谱的问题了——明明用了一模一样的jar命令,在项目根目录打包出来的Jar能正常加载BouncyCastleProvider,跑到子目录里打包就直接抛出ClassNotFoundException。按道理Jar的创建位置不该影响它的内容和运行逻辑,但其实问题大概率出在相对路径的坑上。

问题到底出在哪?

你在子目录执行打包命令时,很可能没给bcprov-jdk15on-159.jar指定正确的相对路径。举个实际的目录结构例子:

my-project/
├── Manifest.txt
├── Main.class
├── bcprov-jdk15on-159.jar
└── build/  # 你用来打包的子目录

如果你进入build/后直接跑:

$ jar cfm MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar

这时候命令里的Manifest.txt、Main.class、bcprov-jdk15on-159.jar都是相对于build/目录的,但这个目录里根本没有这些文件啊!打包出来的Jar自然缺失了依赖的BouncyCastle包,运行时找不到类就很正常了。

怎么修复?

  • 修正依赖文件的相对路径
    回到上面的目录结构,在build/里执行打包命令时,要用上一级路径指向根目录的文件:

    $ jar cfm MyProject.jar ../Manifest.txt ../Main.class ../bcprov-jdk15on-159.jar
    

    这样打包工具才能正确找到并把依赖Jar、主类和Manifest文件都塞进最终的Jar包。

  • 打包后验证Jar内容
    打包完别着急运行,先跑个命令看看Jar里到底有啥:

    $ jar tf MyProject.jar
    

    输出里必须能看到bcprov-jdk15on-159.jar、Main.class和META-INF/MANIFEST.MF这几项,说明打包时确实把这些文件都加进去了。

  • 检查Manifest的Class-Path配置(如果有的话)
    要是你的Manifest.txt里写了Class-Path,得确保这个路径在Jar运行时是有效的。不过从你根目录的成功案例来看,你是直接把依赖Jar打包进主Jar的,这种情况只要路径对了,类加载器就能从嵌套Jar里找到BouncyCastleProvider。

验证修复结果

按正确路径打包后,再运行:

$ java -jar MyProject.jar hello

应该就能正常输出:

provider: BC version 1.59

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:37:02