“找不到或加载主类”是什么意思?


1370

新Java开发人员遇到的一个常见问题是他们的程序无法运行并显示错误消息: Could not find or load main class ...

这是什么意思,是什么原因造成的,以及应该如何解决?


37
请注意,这是一个“自我回答”问题,旨在成为新Java用户的通用参考问答。我找不到现有的足够涵盖此问题的问答(IMO)。
斯蒂芬·C

Answers:


1227

java <class-name>命令语法

首先,您需要了解使用java(或javaw)命令启动程序的正确方法。

常规语法1是这样的:

    java [ <options> ] <class-name> [<arg> ...]

where <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命令执行以下操作:

  1. 搜索com.acme.example.ListUsers该类的编译版本。
  2. 加载课程。
  3. 检查类是否具有main带有签名返回类型修饰符的方法public static void main(String[])。(请注意,方法参数的名称不是签名的一部分。)
  4. 调用该方法,将命令行参数(“ fred”,“ joe”,“ bert”)作为传递给它String[]

Java找不到类的原因

当您收到消息“找不到或加载主类...”时,表明第一步已失败。该java命令无法找到该类。事实上,在“...”的消息将是完全合格的类名java所期待的。

那么为什么找不到课程呢?

原因#1-您在输入classname参数时犯了一个错误

第一个可能的原因是您可能提供了错误的类名。(或者...正确的类名,但格式错误。)考虑以上示例,这里有多种错误的方法来指定类名:

  • Example#1-一个简单的类名:

    java ListUser

    当在诸如之类的包中声明该类时com.acme.example,则必须在命令中使用完整的类名,包括包名java;例如

    java com.acme.example.ListUser
  • Example#2-文件名或路径名而不是类名:

    java ListUser.class
    java com/acme/example/ListUser.class
    
  • Example#3-类名的大小写不正确:

    java com.acme.example.listuser
  • Example#4-错字

    java com.acme.example.mistuser
  • Example#5-源文件名(Java 11或更高版本除外;请参见下文)

    java ListUser.java
  • Example#6-您完全忘记了类名

    java lots of arguments

原因#2-应用程序的类路径指定不正确

第二个可能的原因是类名正确,但是java命令找不到该类。要了解这一点,您需要了解“类路径”的概念。Oracle文档对此作了很好的解释:

所以...如果您正确指定了类名,那么接下来要检查的是您正确指定了类路径:

  1. 阅读上面链接的三个文档。(是的,请阅读它们!Java程序员至少了解 Java类路径机制的基本原理很重要。)
  2. 查看命令行和/或运行java命令时有效的CLASSPATH环境变量。检查目录名和JAR文件名是否正确。
  3. 如果类路径中有相对路径名,请从运行java命令时生效的当前目录中检查它们是否正确解析...。
  4. 检查该类(在错误消息中提到)可以位于有效的类路径上。
  5. 请注意,Windows与Linux和Mac OS 的类路径语法不同。(classpath分隔符;在Windows和:其他操作系统上都使用。如果为平台使用了错误的分隔符,则不会收到明确的错误消息。相反,您将在路径上获得不存在的文件或目录,而该文件或目录将被静默忽略)

原因#2a-错误的目录位于类路径中

将目录放在类路径上时,它在概念上对应于限定名称空间的根。通过将完全限定的名称映射到pathname,类位于该根目录下的目录结构中。因此,例如,如果“ / usr / local / acme / classes”位于类路径上,则当JVM查找名为的类时com.acme.example.Foon,它将查找具有以下路径名的“ .class”文件:

  /usr/local/acme/classes/com/acme/example/Foon.class

如果您已将“ / usr / local / acme / classes / com / acme / example”放在类路径中,那么JVM将无法找到该类。

原因#2b-子目录路径与FQN不匹配

如果您的类FQN为com.acme.example.Foon,那么JVM将在目录“ com / acme / example”中查找“ Foon.class”:

  • 如果您的目录结构与上述模式的包命名不匹配,则JVM将找不到您的类。

  • 如果您尝试通过移动某个类来重命名该类,则该操作也会失败...但是异常stacktrace会有所不同。可能会这样说:

    Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)

    因为类文件中的FQN与类加载器期望找到的内容不匹配。

举一个具体的例子,假设:

  • 你想com.acme.example.Foon上课,
  • 完整的文件路径是/usr/local/acme/classes/com/acme/example/Foon.class
  • 当前的工作目录是/usr/local/acme/classes/com/acme/example/

然后:

# wrong, FQN is needed
java Foon

# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon

# wrong, similar to above
java -classpath . com.acme.example.Foon

# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon

# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon

笔记:

  • 在大多数Java版本中,该-classpath选项可以缩短为-cp。检查相应的手册条目javajavac以此类推。
  • 在类路径中的绝对路径名和相对路径名之间进行选择时,请仔细考虑。请记住,如果当前目录更改,则相对路径名可能会“中断”。

原因#2c-类路径中缺少依赖项

类路径需要包括应用程序依赖的所有其他(非系统)类。(系统类是自动定位的,您几乎不必为此担心。)为了正确加载主类,JVM需要查找:

(注意:JLS和JVM规范允许JVM在某种程度上“延迟”加载类,这可能会在引发类加载器异常时产生影响。)

原因#3-该类已在错误的包中声明

有时会发生某人将源代码文件放入其源代码树中错误的文件夹中的情况,或者他们忽略了package声明。如果您在IDE中执行此操作,则IDE的编译器会立即告诉您有关此信息。同样,如果您使用不错的Java构建工具,则该工具javac将以检测到问题的方式运行。但是,如果您手动构建Java代码,则可以通过这种方式进行处理,以使编译器不会注意到问题,并且生成的“ .class”文件不在您期望的位置。

还是找不到问题?

有很多东西要检查,很容易错过一些东西。尝试将-Xdiag选项添加到java命令行(作为之后的第一件事java)。它将输出有关类加载的各种信息,这可能会为您提供真正问题所在的线索。

另外,请考虑由网站,文档等复制和粘贴不可见或非ASCII字符引起的可能问题。考虑“象形文字”,如果两个字母或符号看起来相同……却不相同。

最后,如果您尝试从中使用不正确签名的JAR文件启动,显然可以遇到此问题(META-INF/*.SF)


的替代语法 java

使用.NET启动Java程序的语法有3种java command

1)用于启动“可执行” JAR文件的语法如下:

  java [ <options> ] -jar <jar-file-name> [<arg> ...]

例如

  java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred

入口点类的名称(即com.acme.example.ListUser)和类路径在JAR文件的MANIFEST中指定。

2)从模块(Java 9和更高版本)启动应用程序的语法如下:

  java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]

入口点类的名称由其<module>自身定义,或由optional给出<mainclass>

3)从Java 11开始,您可以编译并运行一个源代码文件,并使用以下语法运行它:

  java [ <options> ] <sourcefile> [<arg> ...]

在哪里(通常)是带有后缀“ .java”的文件。

有关更多详细信息,请参阅java所用Java版本的命令的官方文档。


集成开发环境

典型的Java IDE支持在IDE JVM本身或子JVM中运行Java应用程序。这些通常不受此特定异常的影响,因为IDE使用其自身的机制来构造运行时类路径,标识主类并创建java命令行。

但是,如果您在IDE背后进行操作,则仍然有可能发生此异常。例如,如果您先前已在Eclipse中为Java应用程序设置了Application Launcher,然后在不通知Eclipse的情况下将包含“ main”类的JAR文件移动到了文件系统中的其他位置,则Eclipse会无意间启动JVM。具有不正确的类路径。

简而言之,如果您在IDE中遇到此问题,请检查IDE的状态是否过旧,项目引用损坏或启动器配置损坏。

IDE可能也很容易混淆。IDE是非常复杂的软件,包含许多交互部分。这些部分中的许多部分都采用了各种缓存策略,以使IDE整体具有响应能力。这些有时可能会出错,并且一种可能的症状是启动应用程序时出现问题。如果您怀疑这可能发生,那么值得尝试其他事情,例如重新启动IDE,重建项目等等。


其他参考


43
当我尝试使用第三方库运行班级时遇到了这个问题。我调用java的是这样的:java -cp ../third-party-library.jar com.my.package.MyClass; 这不起作用,而是有必要将本地文件夹也添加到类路径中(由分隔:,例如:java -cp ../third-party-library.jar:. com.my.package.MyClass,那么它应该起作用
lanoxx 2014年

22
经过多年的Java编程,我仍然设法在此页面上结束。对我而言,问题在于类路径语法与操作系统有关。我是Windows编程的新手,却一无所知。
按键

5
附加说明,第2点救救我!令人悲哀地看到,java并不表示它没有找到一个导入的类,而是主类你想运行。尽管我确信这是有原因的,但这会产生误导。我遇到的情况java是确切知道我的课在哪里,但是找不到导入的课之一。它没有这么说,而是抱怨找不到我的主要班级。真的很烦
MSX

我在Eclipse中两次遇到此问题。第一次main()的签名错误。第二次我重命名了.jar,即使我将新的.jar添加到了构建路径中,Eclipse也没有找到旧的.jar,因此该项目无法编译,并出现此错误。我必须从项目>属性> Java构建路径>库中删除.jar文件。
GregT

我已经第三次遇到了。我已经从Windows 10批处理文件运行该程序,并将.jar名称放入变量中(用“ -cp%jarname%; lib *”调用)。我错误地在jarname的末尾放置了额外的空格,这导致了错误。帽子戏法:)
GregT

239

如果您的源代码名称是HelloWorld.java,则编译后的代码将是HelloWorld.class

如果使用以下命令调用它将收到该错误:

java HelloWorld.class

而是使用以下命令:

java HelloWorld

3
问题在于,该解决方案仅适用于默认包中声明的Java类,而没有JAR文件依赖性。(即使是那样,也并非总是如此。)大多数Java程序并不是那么简单。
斯蒂芬·C

1
如Stephen所说,这仅适用于“默认包”-这意味着文件顶部没有包声明。为了对某些代码进行快速测试,我做到了:javac TestCode.java随后java TestCode
某处某人

这对我没有用。它仍然说:“无法找到或加载主类HelloWorld”
Jim Jim

java -jar HelloWorld.jar也是一个选项
BMaximus

12
我需要做的java -classpath . HelloWorld
克里斯·普林斯

136

如果您的类在软件包中,则必须转到cd项目的根目录并使用该类的完全限定名称(packageName.MainClassName)运行。

例:

我的课在这里:

D:\project\com\cse\

我的主要班级的全名是:

com.cse.Main

所以我cd回到根项目目录:

D:\project

然后发出java命令:

java com.cse.Main

该答案是为了挽救新手Java程序员,避免他们因常见错误而感到沮丧,建议您阅读已接受的答案,以获取有关Java类路径的更深入的知识。


2
这个答案构成了全部假设。还有其他方法可以实现这一目标。我建议大家不要花时间阅读上面的建议,而是花些时间阅读我的答案中的链接,这些链接解释了Java类路径的工作方式。最好了解您在做什么...
Stephen C

2
这个答案做出了我所需要的确切假设:)我位于.class文件的目录中,而java.exe无法正常工作。一旦我在上面cd-ed并运行了命令行中包含的程序包名称,它就起作用了。
尼克·康斯坦丁,

61

如果您在中定义了主类和主方法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在目录目录中./com/test/Main.Java。并在根目录中使用java com.test.Main


1
请参阅我的答案的“附加说明#1”。为了更好地解释这个问题。
Stephen C

14
@StephenC是的,您的答案比较完整(当然是+1),但是这个特定的答案中包含“包装”一词,这使我可以快速找到所需的内容。而且有效。因此+1 Razavi。StephenC,您缺少我刚接触Java时所需的简单包装示例。
kmort

5
这正是我的问题。我一直在阅读大量Java文档,而这个具体示例正是我所需要的
John

1
是的,具体的例子很好,这很好用。我敢肯定主要答案是非常彻底的,但是很难看到森林的树。不错的一个@Razavi
Pixel

1
我喜欢这个简短实用的答案,而不是接受的答案!
Spara

46

当相同的代码在一台PC上运行但在另一台PC上显示错误时,我发现的最佳解决方案是按以下方式进行编译:

javac HelloWorld.java
java -cp . HelloWorld

2
这不是一个好的建议。您取决于未设置CLASSPATH环境变量,或者其值与“。”一致。是的,它在很多情况下都有效,但在其他情况下则无效。
斯蒂芬·C

好吧,肯定javac -classpath . HelloWorld.java会奏效的!在您的情况下,这是一个更好的解决方案。
斯蒂芬·C

2
如果您将“ com.some.address软件包”作为第一行-这将无法工作。您将需要注释掉“包裹地址”

1
@Joe-该hack(注释一下程序包)将起作用(在某些情况下),但这不是一个好主意。一个更好的主意是学习/了解导致问题的原因并实施正确的解决方案。
斯蒂芬C,

36

帮助我的是在命令行上指定类路径,例如:

  1. 新建一个文件夹, C:\temp

  2. 在中创建文件Temp.java C:\temp,其中包含以下类:

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
  3. 在folder中打开命令行C:\temp,并编写以下命令来编译Temp类:

    javac Temp.java
  4. 运行已编译的Java类,添加-classpath选项以让JRE知道在哪里可以找到该类:

    java -classpath C:\temp Temp Hello!

3
在Ubuntu中,我还必须指定路径。不明白为什么默认情况下它不能使用当前工作目录。我相信Java是由键盘制造商赞助的!!
2014年

1
@gone-原因“。” 默认情况下不在$ PATH中是因为它是一个安全陷阱。 seas.upenn.edu/cets/answers/dot-path.html
Stephen C

对此非常感谢……即使无法确定为什么即使在环境变量中设置了java后,java仍无法找到类路径。
akash89'9

@ akash89 -最有可能的原因是:1)java不看$ CLASSPATH(因为你用-classpath或罐子)或2)类路径的设置并没有在这方面并非环境设置生效,该情况下java是跑; 例如,因为您没有“提供”在正确的shell中添加setenv命令的文件。
史蒂芬C

我仍然收到错误:找不到或加载主类Temp有人可以帮忙!

27

根据错误消息(“找不到或加载主类”),问题分为两类:

  1. 找不到主班
  2. 无法加载主类(这种情况未在接受的答案中充分讨论)

主类不能被发现时有错字或错误的语法完全限定类名,或者没有在所提供的类路径中存在

无法启动类无法加载主类,通常,主类扩展了另一个类,并且该类在提供的类路径中不存在。

例如:

public class YourMain extends org.apache.camel.spring.Main

如果不包括骆驼弹簧,将报告此错误。


“基本上”还有很多其他类别。缺少的超类问题是一个非常不寻常的子案例。(如此不寻常,以至于我从未见过它……在此网站上提出的问题。)
Stephen C

有两个,因为错误显示“无法查找或加载主类”。如果还有其他类别,请告诉我。我已经看过了,所以只想在这里分享它,也许其他人会需要它。
小鹏-ZenUML.com 2015年

1
我会将其修改为“您需要包括启动主类所需的所有类,以避免出现此特定错误”。我不是要说服你。这只是我想看到的一种方式。我在这里只为那些可能会喜欢以这种方式阅读东西的人留下答案。让我们不再进一步讨论:)我将声明更改为“未在接受的答案中进行充分讨论”,并希望您感觉更好。
小鹏-ZenUML.com 2015年

5
此信息至关重要,值得一提(这是唯一提及的答案extends)。我刚刚了解到硬盘的方式,当主类无法加载,因为它扩展了另一个不能被发现,JAVA 不报告其实际的类未找到(不同NoClassDefFoundError)。所以是的,的确发生了,当您不知道这一点时,这就是令人毛骨悚然的情况。
Hugues M.

1
在这种情况下,有什么方法可以准确地指出哪个依赖项类无法加载?
卡洛斯·伊瓦拉

16

在这种情况下,我遇到了这样的错误:

java -cp lib.jar com.mypackage.Main

它适用;于Windows和:Unix:

java -cp lib.jar; com.mypackage.Main

是。这很可能是因为您Main不在JAR文件中。-cp lib.jar;表示与-cp lib.jar;. 当前路径相同,即当前目录包含在类路径中。
斯蒂芬·C

最终解决了Unix问题..谢谢(与:合作)
Vicky

16

尝试-Xdiag

史蒂夫·C的答案很好地涵盖了可能的情况,但有时要确定是否找不到加载该类可能并不那么容易。使用java -Xdiag(自JDK 7起)。这会打印出一个不错的堆栈跟踪,从而提示消息Could not find or load main class消息的含义。

例如,它可以将您指向无法找到的主类使用的其他类,并阻止主类加载。


16

使用以下命令:

java -cp . [PACKAGE.]CLASSNAME

示例:如果您的类名是从Hello.java创建的Hello.class,则使用以下命令:

java -cp . Hello

如果您的文件Hello.java位于com.demo软件包中,请使用以下命令

java -cp . com.demo.Hello

在JDK 8中,很多情况下都发生了类文件存在于同一文件夹中的情况,但是java命令期望使用类路径,因此,我们添加-cp .了当前文件夹作为类路径的引用。


这仅在简单情况下有效。更复杂的情况需要更复杂的类路径。
斯蒂芬C,

对于>> really <<简单情况,-cp .则没有必要,因为如果$CLASSPATH未设置,.则为默认类路径。
斯蒂芬·C

没有斯蒂芬,在Windows中很多时候默认的classpath不起作用。我在三台不同的机器上进行了尝试,您也可以尝试一下。
shaILU

那可能是因为您实际上在某个地方设置了%CLASSPATH%环境变量。如果这样做,则说明您没有使用默认的类路径。(echo %CLASSPATH%输出什么?)不,因为我没有Windows PC,所以无法检查。
斯蒂芬·C

2
当我尝试从命令行运行一个简单程序时,这对我
很有用

15

有时,可能导致问题的原因与主类无关,而我不得不艰难地找到答案。这是我搬迁的参考图书馆,它给了我:

找不到或加载主类xxx Linux

我只是删除了该引用,将其再次添加,然后再次正常工作。


1
听起来问题出在您的IDE中,由于项目中的“引用”损坏,您的类路径不正确。我将更新我的答案以解决这种情况。
Stephen C

@StephenC和EduardoDennis,也是在这里,也缺少一个jar,该jar包含一个主类要实例化的接口。因此,错误消息过于广泛。如果没有找到类文件,我应该说“找不到”,如果缺少其他东西但不是文件本身,那么我应该说“无法加载(缺少依赖项)”,因此,如果仅关注焦点,则错误消息过于广泛会误导在它的“查找”部分上:(
Aquarius Power

@AquariusPower-应该为缺少类的“原因”异常增加了一个“堆栈跟踪”。如果您想向Java开发人员建议他们更改一条错误消息,该消息已经说了20多年了……请放心。(我认为错误消息是正确的。问题在于>> you <<收窄了错误的子句。)
Stephen C

@StephenC我的意思是,如果主类文件是否可用,他们肯定可以访问该信息,因此为什么不向我们显示一条更好的错误消息,指出该文件已丢失。另一方面,他们也可以说“找到了文件但无法加载”,我们将立即专注于依赖项,而不是花半天时间研究和测试要理解的东西。只是我的意思是:)。他们可能会在20多年内以有限的方式做到这一点,但是他们可以改善它,我们在这里表示,通过我们的批评和投诉,这种情况将会发生!:D
水瓶座力量

请理解>> I <<的意思。在对3年问答的一些模糊评论中抱怨它并不会取得任何成就。可能会故意对您的投诉采取行动的人不会注意到它。如果您想做些建设性的工作,请提交补丁。(我不评估您的机会,但比您只是抱怨的机会大。)
Stephen C

10

在这种情况下,您有:

无法找到或加载主类

这是因为您使用的是“ -classpath”,但破折号java与命令提示符下使用的破折号不同。我有从记事本复制和粘贴到cmd的问题。


2
哇!那是一个完全奇怪的原因!(但是使用正确的记事本代替真正的文本编辑器是正确的:
Stephen C

10

我遇到了同样的问题,最后发现了我的错误:)我使用了此命令进行编译,并且可以正常工作:

javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java

但是此命令对我不起作用(我找不到或加载主类qrcode):

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode

最后,我只是在类路径的末尾添加了':'字符,问题得以解决:

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode

7

就我而言,出现错误是因为我提供了源文件名而不是类名。

我们需要将包含main方法的类名提供给解释器。


是。请参阅我的示例#2来指定类名的错误方法!!
Stephen C

7

如果您的情况特别类似于我的情况,这可能对您有所帮助:作为初学者,我在尝试运行Java程序时也遇到了此问题。

我像这样编译它:

javac HelloWorld.java

而且我尝试使用相同的扩展名运行:

java Helloworld.java

当我删除.java并重新编写了类似的命令时java HelloWorld,程序运行完美。:)


2
这是因为您正在执行.java的编译版本。它实际上正在执行.class文件
Jason V

记录下来,这与我的答案中的原因#1,示例#5相同
Stephen C

6

这里的所有答案似乎都是针对Windows用户的。对于Mac,classpath分隔符是:,不是;。由于设置类路径使用时;未引发设置错误,因此如果从Windows到Mac,则很难发现。

这是相应的Mac命令:

java -classpath ".:./lib/*" com.test.MyClass

在此示例中,程序包所在的位置com.test以及lib类路径中还将包含一个文件夹。


2
在Linux上和在Mac上一样。
Alex78191

为什么/*有必要?
Alex78191

这是一个通配符语法。(这不是强制性的。您可以根据需要明确列出JAR。)
Stephen C,

6

在此处输入图片说明

类文件位置: C:\ test \ com \ company

文件名: Main.class

完全限定的类名称: com.company.Main

命令行命令:

java  -classpath "C:\test" com.company.Main

请注意,此处的类路径不包含\ com \ company


6

我花了很多时间来解决这个问题。我以为我在某种程度上错误地设置了我的类路径,但是问题是我输入了:

java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool  

代替:

java -cp C:/java/MyClasses utilities/myapp/Cool   

我认为完全限定的含义是包括完整的路径名而不是完整的包名。


我已经更新了答案,以解决这种困惑。
斯蒂芬·C

2
这些都不是正确的。该类必须以utilities.myapp.Cool或其包名(如果有)的形式给出。
user207421'2

5

首先使用此命令设置路径;

set path="paste the set path address"

然后,您需要加载程序。在存储的驱动器中键入“ cd(文件夹名称)”并进行编译。例如,如果我的程序存储在D驱动器上,则键入“ D:”,然后按Enter键并键入“ cd(文件夹名称)”。


4
这无济于事。这个问题是关于Java程序的,而不是普通的可执行文件。Java不使用PATH来定位任何内容,如果“ cd”有帮助,那么它是靠运气而不是凭判断来实现的。
斯蒂芬·C

if "cd" helps then it by luck rather than by judgement。这是错误的(我相信),因为java .默认使用当前目录作为类路径的一部分。
GKFX

2
@GKFX-这就是我的意思。除非您知道使用的是默认的类路径(或带有“。”的类路径),否则“ cd”将无效。该解决方案更多的是靠运气(即猜测/希望“。”在类路径上)而不是通过判断(即检查“。”在类路径上)来工作。此外,您对默认值不正确。Java使用“。” 默认情况下为类路径,而不默认为类路径的一部分。
Stephen C

5

解决我的问题的原因是:

右键单击要运行的项目/类,然后单击Run As-> Run Configurations。然后,您应该修复现有配置或通过以下方式添加新配置:

打开Classpath选项卡,单击Advanced...按钮,然后添加项目的bin文件夹


5

如果使用Maven生成JAR文件,请确保在pom.xml文件中指定主类:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>class name us.com.test.abc.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

4

这是一个特定的情况,但是由于我是来此页面寻找解决方案的,但没有找到解决方案,因此将其添加到此处。

Windows(已通过7测试á)在类和程序包名称中不接受特殊字符(如)。但是,Linux确实如此。

.jar在NetBeans中构建一个并尝试在命令行中运行时发现了这一点。它在NetBeans中运行,但不在命令行中运行。


4

在Windows上.;,将CLASSPATH值放在开头。

的。(点)表示“在当前目录中查找”。这是一个永久的解决方案。

您也可以使用set将它设置为“一次” CLASSPATH=%CLASSPATH%;.。只要您的cmd窗口处于打开状态,此操作就会持续​​。


1
此建议可能有帮助,也可能没有帮助。如果类树包含当前目录中的类,则将有所帮助。如果不是,那不会。我实际上不会这样做。相反,我将创建一个单行包装脚本,无论用户是否在“正确的”目录中,该脚本都可以工作。
斯蒂芬·C

4

您确实需要从src文件夹中执行此操作。在此处键入以下命令行:

[name of the package].[Class Name] [arguments]

假设您的类称为CommandLine.class,代码如下所示:

package com.tutorialspoint.java;

    /**
     * Created by mda21185 on 15-6-2016.
     */

    public class CommandLine {
        public static void main(String args[]){
            for(int i=0; i<args.length; i++){
                System.out.println("args[" + i + "]: " + args[i]);
            }
        }
    }

然后,您应该cd转到src文件夹,并且需要运行的命令如下所示:

java com.tutorialspoint.java.CommandLine this is a command line 200 -100

命令行上的输出将是:

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

2
一个类不能称为“ CommandLine.class”。那将是Java语法错误。(您的意思是,包含编译类的文件称为“ CommandLine.class” ...)。另一个问题是,仅当您将代码>> into <<源目录树编译时,“ cd到源目录”的指令才有效。最后,如果您的编译使用了“ -cp”参数,那么在运行时就需要一个等效选项。
史蒂芬·C

在我的项目中,我的根目录有src文件夹和bin文件夹。我必须cd进入src然后运行java ../bin com.blah.blah.MyClass对我有用的命令。因此,感谢您的提示!
tamj0rd2

3

在Java中,当您有时使用java可执行文件从命令行运行JVM并尝试从具有公共静态void main(PSVM)的类文件启动程序时,即使将classpath参数设置为JVM是准确的,并且类文件位于类路径中:

Error: main class not found or loaded

如果无法加载带有PSVM的类文件,则会发生这种情况。一个可能的原因是该类可能正在实现接口或扩展不在类路径上的另一个类。通常,如果某个类不在类路径中,则抛出的错误将指示错误。但是,如果扩展或实现了正在使用的类,则java无法加载该类本身。

参考:https : //www.computingnotes.net/java/error-main-class-not-found-or-loaded/


1
您是否阅读了接受的答案?您的答案是否添加了新内容?
斯蒂芬·C

1
@StephenC我试图通过查看“原因”类别及其要点来在列表中找到原因。我在“原因#1”和“原因#2”标题中找不到匹配点,似乎与我的情况不符(因为我确定类路径本身没有问题)。我已经通过执行实验找到了原因,但由于在我的情况下显示了“未找到主类”错误,我很惊讶,因为实现接口不在类路径上。当然,您可以说“您应该阅读本文中描述的所有内容”,但在我看来,您的原因清单可以得到改善。
gumkins

3

使用Windows PowerShell中公告java-cp选项运行时,您可能会看到类似以下错误:

The term `ClassName` is not recognized as the name of a cmdlet, function, script ...

为了使PowerShell能够接受命令,该-cp选项的参数必须包含在引号中,如下所示:

java -cp 'someDependency.jar;.' ClassName

以这种方式形成命令应该允许Java正确处理classpath参数。


3

在测试Java MongoDB JDBC连接时,我也遇到类似的错误。我认为最好总结一下我的最终解决方案,这样将来任何人都可以直接查看这两个命令,并且可以继续进行下去。

假设您位于Java文件和外部依赖项(JAR文件)所在的目录中。

编译:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • -cp-类路径参数; 一张一张地传递所有依赖的JAR文件
  • * .java-这是具有主要方法的Java类文件。固态硬盘

跑:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • 所有依赖项JAR文件结束后,请务必注意冒号(Unix)/逗号(Windows)
  • 最后,观察没有任何扩展名的主类名称(没有.class或.java)

所有这些都假定1)JavaMongoDBConnection没有包,并且2)您不更改目录。至少可以说,它是脆弱的。通过不解释问题,它将导致新手在这种方法行不通的情况下尝试这种方法。简而言之,它鼓励“伏都教编程技术”:en.wikipedia.org/wiki/Voodoo_programming
Stephen C

3

好的,已经有很多答案了,但是没有人提到文件权限可能是罪魁祸首的情况。

运行时,用户可能无权访问JAR文件或路径的目录之一。例如,考虑:

Jar文件中 /dir1/dir2/dir3/myjar.jar

拥有JAR文件的User1可以执行以下操作:

# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar

但这仍然行不通:

# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram

这是因为正在运行的用户(User2)无权访问dir1,dir2或javalibs或dir3。当User1可以看到文件并可以访问文件时,这可能会使某人发疯,但是User2仍然会发生错误。


2

执行mvn eclipse:eclipse 此操作后出现此错误,这使我的.classpath文件有些混乱。

不得不改变线路.classpath

<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>

<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**"  output="target/classes" />

2

我无法使用此处说明的解决方案解决此问题(尽管所给出的答案无疑已经清除了我的概念)。我两次都遇到了这个问题,每次都尝试了不同的解决方案(在Eclipse IDE中)。

  • 首先,我main在项目的不同类中遇到了多种方法。因此,我main已从后续类中删除了该方法。
  • 其次,我尝试了以下解决方案:
    1. 右键单击我的主项目目录。
    2. 前往源代码,然后清理并坚持默认设置并完成。完成一些后台任务后,您将被定向到主项目目录。
    3. 之后,我关闭了我的项目,重新打开它,然后繁荣起来,我终于解决了我的问题。

1
删除main方法无法解决问题。具有多个入口点的应用程序在技术上没有错。
斯蒂芬·C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.