1. 前言
实习做NLP任务时,在离线train获得模型
bin
文件后,在部署到线上之前经常需要测试一下QPS等指标,用
Java
写了测试流程,用
Maven
打成
jar
包之后,上传到开发机。打包是用的
clean package
命令,但是传到服务器上却报
main NoClassDefFoundError
错误,遇到过两次,故作记录
2. 错误原因
NoClassDefFoundError是因为Java虚拟机 在编译时能找到合适的类,而在运行时不能找到合适的类 导致的错误。
3. 与ClassNotFoundException的区别
两者区别还蛮大的。
NoClassDefFoundError发生在JVM在动态运行时,根据提供的类名,在classpath中需要找到对应的类进行加载,当找不到这个类时,就会发生NoClassDefFoundError错误。
ClassNotFoundException完全是由于环境的问题导致的,在编译时就会报错,相对较容易解决。
4. 问题描述
我在项目引用了外部jar包,由于jar本身不支持maven,所以在使用和打包时,将jar文件添加在lib路径里,并在pom.xml文件里显式的配置了绝对引用路径,如下:
<dependency>
<groupId>com.github.XXX</groupId>groupId>
<artifactId>XXX</artifactId>artifactId>
<version>0.1</version>version>
<scope>system</scope>scope>
<systemPath>/home/your/jar/path</systemPath>systemPath>
</dependency>dependency>
借助clean package
命令进行打包,将jar包传到服务器,运行如下命令:java -cp XXX-1.0-SNAPSHOT-jar-with-dependencies.jar:. com.XXX.FasttextClassifier
,终端提示找不到引用的外部类。
5. 解决方法
将引用的外部jar包在开发机上编辑生成jar包文件,更改运行命令为:java -cp XXX-1.0-SNAPSHOT-jar-with-dependencies.jar:my/path/to/XXX.jar:. com.XXX.FasttextClassifier
,可以运行。
感觉是打包的问题,貌似并没有把依赖的包打包进来,在开发机上运行,还需要将引用的jar包路径用-cp
命令复制到classpath路径里。
6.常见的排查原因
对应的class在java的classpath
中不可用
你可能用jar命令运行你的程序,但类并没有在jar文件的manifest
的classpath
属性中定义
可能程序的启动脚本覆盖了原来的classpath
的环境变量