Linux命令行创建可执行JAR遇ClassNotFoundException问题求助
打包带包声明的Java类为可执行JAR时遭遇ClassNotFoundException的解决方法
问题场景
在Ubuntu命令行下,我尝试将一个带main方法的Java类打包成可执行JAR,执行时始终抛出ClassNotFoundException。
我的错误操作流程
- 编写
HelloWorld.java文件:
package hello; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } }
- 编译生成class文件:
$ javac HelloWorld.java
- 执行打包命令:
$ jar cvfe helloWorld.jar hello.HelloWorld.class *.class
- 运行JAR时报错:
$ java -jar helloWorld.jar Error: Could not find or load main class hello.HelloWorld.class Caused by: java.lang.ClassNotFoundException: hello.HelloWorld.class
查看JAR内的META-INF/MANIFEST.MF,发现主类配置错误:
Manifest-Version: 1.0 Created-By: 21.0.2 (Oracle Corporation) Main-Class: hello.HelloWorld.class
我也曾尝试移除Java文件的包声明和打包命令中的包名,但依旧出现相同异常。
正确解决步骤
经过调整后问题已解决,正确操作如下:
- 调整目录结构:将
HelloWorld.java放入名为hello的子文件夹中,保证目录结构与包声明一致(包名hello对应文件夹hello)。 - 编译class文件:在
hello文件夹的上级目录执行编译命令:
$ javac hello/HelloWorld.java
- 正确打包JAR:执行打包命令时,主类名不要添加
.class扩展名:
$ jar cvfe helloWorld.jar hello.HelloWorld hello/*.class
错误原因解析
- 主类名格式错误:打包时错误地给主类名加上了
.class后缀,导致MANIFEST.MF中的Main-Class配置为hello.HelloWorld.class,而Java虚拟机需要的是类的全限定名(即hello.HelloWorld,不带文件扩展名)。 - 类路径结构不匹配:带包声明的Java类,编译后的
.class文件必须放在与包名对应的子目录下,否则JAR内的类路径不符合Java包结构规范,虚拟机无法正确定位并加载类。
内容的提问来源于stack exchange,提问作者Devlinite
相关产品推荐
相关产品推荐

