Jar文件中找不到或加载主类

73

我想使用以下代码加载一个jar文件:

@echo off
java -jar Test.jar
pause

使用清单文件

Manifest-Version: 1.0
Main-Class: classes.TestClass
在 Jar 目录中,当我提取它时,我可以清楚地看到一个 classes\TestClass 文件。
编辑:classes.TestClass确实有一个public static void main(String[] args)classes.TestClass中的包声明是package classes;
但我仍然不断收到错误消息。
Could not find or load main class classes.TestClass

我已经尝试了所有能找到的方法解决这个问题,但似乎都没有用。

我尝试编辑类路径,重新制作清单文件,安装新的JRE。

还应该做些什么?


1
TestClass 是否包含主函数? - Baz
3
是的,它有一个主方法。 - Austin
3
你确定 TestClass 的包名是 classes 吗? - Hakan Serce
1
TestClass是否在classes包中?我建议先从命令行运行文件一次。如果成功了,再继续进行。 - Arham
2
你把输出目录中的“classes”和包中的“classes”混淆了。 - chrylis -cautiouslyoptimistic-
显示剩余3条评论
22个回答

41

我用这种方法使它工作了:

TestClass.Java

package classes;

public class TestClass {

    public static void main(String[] args) {
        System.out.println("Test");
    }

}

使用命令行上的 javac 命令生成 TestClass.class 文件,并将其放置在一个名为 classes/ 的文件夹中。

MANIFEST.MF

Manifest-Version: 1.0
Main-Class: classes.TestClass

然后运行

jar cfm test.jar MANIFEST.MF classes/

然后运行它

java -jar test.jar

7
我想指出答案中隐含的一点:重要的是“cd”到路径,该路径将用作在没有jar文件的情况下运行TestClass.class时使用的类路径。例如,“cd /MyEclipseWorkspace/MyProject/bin”。如果相反,jar文件使用类文件的绝对路径,则可能会出现“找不到或加载主类”的错误。例如,这样是错误的:jar cfm test.jar manifest.txt /absolutepath/classes/TestClass.class。 - Corral
1
@Corral的评论不应该被忽视。在阅读它之前,我一直在为解决这个问题而苦恼,现在我的jar文件运行得非常完美。 - Kyle G.
1
>%JAVAHOME%\bin\jar cfM MANIFEST.MF test.jar classes/ 的结果是 test.jar: 没有这个文件或目录,而 MANIFEST.JS 现在已经损坏(它现在是二进制文件)。 - Peter Zhukov

32

如果您在单词“jar”之前错过了破折号,即使出现此错误。

错误命令 java jar test.jar

正确命令 java -jar test.jar


22
运行具有"public static void main"方法的其他包中的类时,可以使用以下命令:

java -cp "您的jar文件的完整路径" package1.package2.packages-hierarchy.ClassHavingMain

3
当你给某个东西点踩时,请添加一个解释。 - Matthias Urlichs
1
如果您在与JAR文件相同的目录中,是否必须输入完整路径? - Ungeheuer

12

1.创建名为Manifest.txt的文本文件,其中包含以下内容:

Main-Class: classes.TestClass

2.创建jar包:

jar cfm test.jar Manifest.txt classes/*.class

3.运行jar包:

java -jar test.jar


你能告诉我你的java路径和类路径设置如何吗?在回答之前,有一件事你可以尝试一下。试着通过命令行来运行同样的TestClass,而不是通过Eclipse。 - Arham
我可以使用命令行轻松运行该类,以及其他Java命令,如javac。 - Austin

11

我知道这是一个老问题,但最近我遇到了这个问题,没有一个答案能帮助我。然而,Corral在Ryan Atkinson的回答中的评论提示了我问题所在。

我的所有编译后的类文件都在target/classes目录下,这些不是我的包。我尝试使用jar cvfe App.jar target/classes App命令将其打包,在我的项目根目录下,因为我的App类位于默认未命名包中。

这样是行不通的,因为新创建的App.jar文件将会把App.class放在target/classes目录下。如果您试图使用java -jar App.jar运行此jar文件,它会抱怨找不到App类。这是因为App.jar内部的包与项目中实际的包不匹配。

可以通过直接从target/classes目录创建jar文件来解决这个问题,使用jar cvfe App.jar . App命令。在我看来,这相当麻烦。

简单的解决方案是使用-C选项列出要添加的文件夹,而不是使用默认方式列出文件夹。因此,在我的情况下,正确的命令是java cvfe App.jar App -C target/classes .。这将直接将target/classes目录中的所有文件添加到App.jar的根目录,从而解决了问题。


4
这是唯一帮助我的答案!谢谢。除了使用(cd)进入包/类所在的文件夹之外,还有其他方法吗? - noctua
我已经阅读了数十个关于这个主题的不同帖子和文档。除了你的答案,其他都没有用。谢谢。 - Jason Kim
1
@Log2 我知道,但是看看 noctua 在评论中问的问题。他可能没有看到你回答中的最后一句话。他问的问题可以通过你指出并我重复的内容得到回答。我试图对 noctua 有所帮助。我在评论中也感谢了你,因为你的回答是唯一有用的。 - Jason Kim
1
@JasonKim 对不起,我没有意识到你只是在为他重复。我并不是想点名批评你或者什么的。 - Log2
@Log2 没问题 - Jason Kim
显示剩余2条评论

8

我曾经因为从Microsoft Word文档中复制和粘贴代码而遇到了同样的问题。看起来使用了稍微不同类型的破折号-字符,当我用正确的-替换了较长的破折号字符后,程序就正常执行了。


1
真的,对我来说大多数情况下都是从Outlook或Skype复制时发生的。 - Santosh Kumar Arjunan

7
这个错误信息可能的原因是:主类继承(或实现)了不在类路径上的另一个类(或接口)。

4
这是非常难以调试的,没有完整信息很困难。
目前看来最有可能的两件事是要么jar文件中的文件未存储在JAR内的目录中,要么它不是正确的文件。
你需要存储TestClass.class——一些新手存储源文件TestClass.java。
并且你需要创建jar文件,使得TestClass.class出现在classes路径下。确保它不是“/classes”。使用zip查看文件,并确保它具有“classes”的路径。

天啊,这就是发生在我身上的事情!我的Ant Jar任务有一个“/”前缀,但需要“”。 - escape-llc

3
我曾遇到一个奇怪的问题,当我尝试启动一个非常简单的Scala程序时,MANIFEST.MF中的错误条目导致了加载失败。

错误的内容:

Main-Class: jarek.ResourceCache
Class-Path: D:/lang/scala/lib/scala-library.jar

正确的写法:

Main-Class: jarek.ResourceCache
Class-Path: file:///D:/lang/scala/lib/scala-library.jar

使用错误的版本,我收到了一个像操作者一样的神秘信息。可能应该说一些像“解析清单文件时出现了格式错误的url异常”的话。

在清单文件中使用绝对路径是IntelliJ用来为程序提供长类路径的方式。


这并没有帮助我。我需要为我添加的所有类路径添加file:///吗? - MR AND
1
是的,所有的JAR包都是必需的。 - Jarekczek

3

我曾经遇到过类似的问题,在Linux系统中,我通过给包含jar文件的所有父文件夹授予执行权限来解决问题。

例如:

/folder1/folder2/folder3/executable.jar

对于当前用户,需要为这3个文件夹(folder1、folder2和folder3)以及可执行的jar文件都赋予执行权限,否则会返回“找不到或加载主类…”的错误信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接