编译生成jar包运行时出现ClassNotFoundException错误该如何解决?
问题根因
该错误是运行jar时JVM无法找到pdfbox依赖类导致的,核心原因有2个:
- 编译阶段指定的classpath仅对编译生效,运行
java -jar时JVM会完全忽略外部的classpath参数,仅读取jar包内META-INF/MANIFEST.MF文件的Class-Path配置查找依赖 - 你当前的打包逻辑既没有将pdfbox依赖打入jar包,也没有在manifest文件中配置依赖的查找路径
额外冗余问题:你执行了两次javac编译命令,第一次不带依赖的编译完全可以省略,直接执行第二次带lib依赖的编译即可。
排查解决步骤
方案1:配置manifest+保留本地依赖目录(操作最简单)
- 编辑项目根目录下的
manifest.txt,添加以下配置,注意配置末尾必须保留一个空行,否则最后一行配置不会被识别:
Main-Class: myapp.myapp Class-Path: lib/pdfbox-app-2.0.24.jar
其中Main-Class是主类的全限定名(包名+类名),Class-Path指定了依赖jar相对于运行jar时当前工作目录的路径。
2. 重新打包,无需将无用的src目录打入jar:jar -cvfm myapp.jar manifest.txt -C bin/ .
3. 运行时保证当前目录下存在lib文件夹,且其中存放pdfbox-app-2.0.24.jar,直接执行java -jar myapp.jar即可正常运行。
方案2:打Fat Jar(生成可独立运行的jar包,无需依赖外部lib目录)
如果希望生成的jar可以单独运行,不需要携带lib目录,可以将依赖的class全部打入同一个jar包:
手动操作步骤
# 进入bin目录 cd bin # 解压pdfbox依赖的所有class到当前目录 jar -xvf ../lib/pdfbox-app-2.0.24.jar # 返回项目根目录 cd .. # 打包所有class和manifest配置 jar -cvfm myapp.jar manifest.txt -C bin/ .
推荐优化方式
后续开发建议使用Maven/Gradle等构建工具管理依赖,通过配置打包插件即可一键生成Fat Jar,无需手动解压合并依赖。
验证方法
可以执行jar -tf myapp.jar查看jar包内的文件列表,确认配置和依赖是否正确;也可以执行jar -xf myapp.jar META-INF/MANIFEST.MF解压出manifest文件,检查配置是否生效。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

