使用-cp参数在CMD中运行含classes目录的JAR文件遇类找不到异常
JAR文件运行抛出ClassNotFoundException的问题
问题场景
我创建的JAR文件结构如下:
myJar.jar |-- classes |-- packageA |-- ClassA.class |-- packageB |-- ClassB.class
相关操作命令
- 创建JAR的命令:
jar -cvf myJar.jar classes - 编译代码的命令:
javac -d classes packageA/ClassA.java packageB/ClassB.java - 尝试运行的命令:
java -cp "myJar.jar;myJar.jar/classes" packageB.ClassB
运行后抛出ClassNotFoundException,其中ClassB包含main方法。测试另一种无classes目录、直接包含包目录的JAR结构时,运行正常:
myJar.jar |-- packageA |-- ClassA.class |-- packageB |-- ClassB.class
问题原因
Java类加载器会以类路径中的目录或JAR根目录为基准,匹配类的全限定名。当JAR中包含classes目录时,ClassB在JAR内的实际路径是classes/packageB/ClassB.class,但指定的类名是packageB.ClassB,类加载器会在JAR根目录下查找packageB/ClassB.class,因此找不到目标类,抛出异常。
解决方法
方法一:调整打包方式(推荐)
进入classes目录后再执行打包命令,让JAR根目录直接对应包结构:
cd classes jar -cvf ../myJar.jar *
生成的JAR结构即为测试正常的样式,之后用以下命令运行即可:
java -cp myJar.jar packageB.ClassB
方法二:修改类路径(不推荐)
如果必须保留JAR中的classes目录,需将JAR内的classes目录加入类路径,注意不同系统的分隔符差异:
- Windows系统:
java -cp "myJar.jar;myJar.jar!/classes" packageB.ClassB - Linux/macOS系统:
java -cp "myJar.jar:myJar.jar!/classes" packageB.ClassB
内容的提问来源于stack exchange,提问作者Prashant Kumar
相关产品推荐
相关产品推荐

