新的Java开发人员经常遇到的一个常见问题是,他们的程序无法运行,并显示以下错误信息:Could not find or load main class ...
这是什么意思,它是由什么原因引起的,以及应该如何修复它?
新的Java开发人员经常遇到的一个常见问题是,他们的程序无法运行,并显示以下错误信息:Could not find or load main class ...
这是什么意思,它是由什么原因引起的,以及应该如何修复它?
<类名>
命令语法首先,您需要了解使用 java
(或 javaw
)命令启动程序的正确方式。
正常的语法1如下:
java [ <options> ] <class-name> [<arg> ...]
<option>
是一个命令行选项(以"-"字符开头),<class-name>
是一个完全限定的Java类名,<arg>
是一个传递给您的应用程序的任意命令行参数。
1 - 在本答案的末尾附近还有一些其他的语法描述。
类的完全限定名(FQN)通常以你在Java源代码中编写的方式书写;例如:
packagename.packagename2.packagename3.ClassName
java
命令允许您使用斜杠而不是句点,例如。 packagename/packagename2/packagename3/ClassName
这个看起来像文件路径名,但实际上并不是。请注意,完全限定名是标准的Java术语...不是我刚刚编造来困惑你的 :-)
下面是一个java
命令的示例:
java -Xmx100m com.acme.example.ListUsers fred joe bert
java
命令执行以下操作:
com.acme.example.ListUsers
类的版本。public static void main(String[])
给出的签名、返回类型和修饰符的main
方法。(注意,方法参数的名称不是签名的一部分。)String[]
传递给它。当您收到"Could not find or load main class ..."的消息时,这意味着第一步失败了。java
命令无法找到该类。实际上,消息中的"..."将是java
正在寻找的完全限定类名。
那么为什么它无法找到该类呢?
第一个可能的原因是您可能提供了错误的类名。(或者...正确的类名,但是形式错误。)考虑上面的示例,以下是指定类名的各种错误方式:
示例 #1 - 一个简单的类名:
java ListUser
当类声明在一个包中,比如com.acme.example
,那么在java
命令中必须使用完整的类名,包括包名;例如:
java com.acme.example.ListUser
示例 #2 - 文件名或路径名而不是类名:
java ListUser.class
java com/acme/example/ListUser.class
示例 #3 - 类名的大小写不正确:
java com.acme.example.listuser
示例 #4 - 拼写错误
java com.acme.example.mistuser
示例 #5 - 源文件名(Java 11或更高版本除外;请参见下文)
java ListUser.java
示例 #6 - 你完全忘记了类名
java 大量的参数
第二个可能的原因是类名是正确的,但是java
命令无法找到该类。要理解这一点,您需要了解"类路径"的概念。这在Oracle文档中有很好的解释:
java
命令文档所以...如果您已经正确指定了类名,下一步要检查的是您是否正确指定了类路径:
阅读上面链接的三个文档。(是的...要读它们!对于Java程序员来说,至少要理解Java类路径机制的基础是很重要的。) /usr/local/acme/classes/com/acme/example/Foon.class
java -cp ../third-party-library.jar com.my.package.MyClass
;但是这种方法不起作用,需要将本地文件夹也添加到类路径中(用冒号“ : ”分隔),像这样:java -cp ../third-party-library.jar:. com.my.package.MyClass
,然后它应该可以正常工作。 - lanoxxjava
并没有说它找不到一个已导入的类,而是找不到你试图运行的主类,真是令人沮丧。尽管我相信这背后肯定有原因。我遇到了这种情况,java
确切地知道我的类在哪里,但它无法找到其中一个已导入的类。它抱怨找不到我的主类,这实在让人恼火。 - MSXError: Could not find or load main class =
错误是由于spark.properties文件错误引起的,其中我在spark.driver.extraJavaOptions -Dlog4j.configuration = log4j.properties
中的等号周围有空格,该选项被声明为spark2-submit cmd行选项的一部分--files hdfs://.../log4j.properties
。删除所有类似行中的空格即可解决此问题。 - codeaperatureHelloWorld.class
。如果您使用以下方式调用它,您将会得到该错误:java HelloWorld.class
改用这个:
java HelloWorld
javac TestCode.java
,然后是java TestCode
。 - Someone Somewherejava -classpath . HelloWorld
。 - Chris Prince如果你的类在包中,那么你需要cd
到项目的根目录并使用完全限定的类名(packageName.MainClassName)运行。
例如:
我的类在这里:
D:\project\com\cse\
我的主类的完全限定名是:
com.cse.Main
因此我cd
回到根项目目录:
D:\project
然后发出java
命令:
java com.cse.Main
这篇回答是为了帮助初学者Java程序员摆脱由一个常见错误引起的挫败感。我建议您阅读已接受的答案以获取有关Java类路径更深入的知识。
java com.firstpackage.Test
不起作用,也不会使用命令java -classpath C:\Users\matuagkeetarp\IdeaProjects\Helloworld\src\com\firstpackage Test.java
设置classpath变量。你能帮忙吗? - Prateek Gautam如果你的源代码中有一个package
关键字(主类在一个包中定义),则应该通过层次目录运行它,使用类的完整名称(packageName.MainClassName
)。
假设有一个源代码文件(Main.java):
package com.test;
public class Main {
public static void main(String[] args) {
System.out.println("salam 2nya\n");
}
}
要运行此代码,您应该将Main.Class
放置在类似目录的包中:
C:\ Users \ workspace \ testapp \com\test\Main.Java
然后将终端的当前目录更改为项目的根目录:
cd C:\Users\workspace\testapp
最后,运行代码:
java com.test.Main
如果你的源代码中没有任何包(package)的名称,可能是因为你使用了错误的命令。假设你的Java文件名为Main.java
,编译后:
javac Main.java
编译后的代码将会是Main.class
如果你使用以下方式调用它,你会得到那个错误:
java Main.class
改为使用这个:
java Main
当同一份代码在一台电脑上运行正常,但在另一台电脑上出现错误时,我发现最好的解决方案是按照以下方式进行编译:
javac HelloWorld.java
java -cp . HelloWorld
javac -classpath . HelloWorld.java
也可以工作!而且在你的情况下这是更好的解决方案。 - Stephen C在命令行上指定类路径对我有所帮助。例如:
创建一个新文件夹,C:\temp
在C:\temp
中创建文件Temp.java,并在其中添加以下类:
public class Temp {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
在文件夹C:\temp
中打开命令行,并输入以下命令编译Temp类:
javac Temp.java
运行编译的Java类,添加-classpath
选项,让JRE知道在哪里找到这个类:
java -classpath C:\temp Temp Hello!
java
没有查看$CLASSPATH(因为您使用了-classpath或-jar),或者2)classpath设置在环境中未设置,该环境在运行java
的上下文中未生效;例如,因为您没有在正确的shell中“源”添加了setenv命令的文件。 - Stephen Cjava -classpath c:\folder\subfoler\myCodeFolder Main
也可以运行Main.class
。 - surfmuggle根据错误信息 ("Could not find or load main class"),问题可以分为两类:
当主类名存在错别字或语法错误,或在提供的类路径中不存在该类时,将出现找不到主类(Main class could not be found)的情况。
当类无法被初始化时,主类无法加载(Main class could not be loaded),通常情况下,主类继承了另一个类,而该类在提供的类路径中不存在。
例如:
public class YourMain extends org.apache.camel.spring.Main
如果没有包含camel-spring,将会报告此错误。NoClassDefFoundError
错误)。所以它确实会发生,在你不知道这一点的情况下,这是一个让人抓狂的局面。 - Hugues M.-Xdiag
标志可能会给你一些提示。 - Oleg Kurbatov使用这个命令:
java -cp . [PACKAGE.]CLASSNAME
示例:如果您的类名是从Hello.java创建的Hello.class,则使用以下命令:
java -cp . Hello
如果你的Hello.java文件在com.demo包内,则使用以下命令
java -cp . com.demo.Hello
在JDK 8中,往往出现类文件与java命令在同一文件夹下的情况,但是java命令需要类路径(classpath),因此我们添加-cp .
选项,以当前文件夹作为类路径的参考。
-cp .
是不必要的,因为如果 $CLASSPATH
未设置,则 .
是默认的类路径。 - Stephen C尝试使用-Xdiag选项。
Steve C的回答对可能出现的情况进行了很好的概述,但有时确定类是否未被找到或加载可能并不容易。可以使用java -Xdiag
(自JDK 7以来)。这将打印出一个漂亮的堆栈跟踪,提供了关于Could not find or load main class
错误信息含义的提示。
例如,它可以指向主类使用但未能找到并阻止了主类加载的其他类。
在这种情况下,我遇到了这样的错误:
java -cp lib.jar com.mypackage.Main
它在Windows中使用;
,在Unix中使用:
:
java -cp lib.jar; com.mypackage.Main