【问题标题】:What does "Could not find or load main class" mean?“找不到或无法加载主类”是什么意思?
【发布时间】:2022-06-12 02:44:04
【问题描述】:

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

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

【问题讨论】:

  • 请注意,这是一个“自我回答”问题,旨在作为新 Java 用户的通用参考问答。我找不到足以涵盖此问题的现有问答(IMO)。
  • 对我来说,它发生在以前工作的项目上......所以我通过“重建项目”来修复它
  • @弗拉迪-“IDE 也可能会简单地感到困惑。IDE 是由许多交互部分组成的非常复杂的软件。其中许多部分采用各种缓存策略,以使 IDE 作为一个整体响应。这些有时可能会出错,一个可能的症状是启动应用程序时出现问题。如果您怀疑这可能会发生,那么值得尝试其他方法,例如重新启动 IDE,重建项目等等。”

标签: java class program-entry-point


【解决方案1】:

java <class-name> 命令语法

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

正常语法1这是:

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

其中&lt;option&gt; 是命令行选项(以“-”字符开头),&lt;class-name&gt; 是完全限定的Java 类名,&lt;arg&gt; 是传递给应用程序的任意命令行参数。


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 参数上犯了一个错误

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

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

      java ListUser
      

      当类在 com.acme.example 等包中声明时,必须使用完整的类名包含java 命令中的包名;例如

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

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

      java com.acme.example.listuser
      
    • 示例 #4 - 一个错字

      java com.acme.example.mistuser
      
    • 示例 #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。 (类路径分隔符在 Windows 上为 ;,在其他系统上为 :。如果您为您的平台使用了错误的分隔符,您将不会收到明确的错误消息。相反,您将在将被静默忽略的路径。)

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

      当您将目录放在类路径上时,它理论上对应于限定名称空间的根目录。类位于该根目录下的目录结构中,通过将完全限定名映射到路径名.例如,如果“/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 将找不到您的类。

      • 如果你尝试改名通过移动一个类,它也会失败......但异常堆栈跟踪会有所不同。很容易说这样的话:

        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 字符可能导致的问题。并考虑“同形文字”,其中两个字母或符号看起来相同......但不是。

      如果您在META-INF/*.SF 中有无效或不正确的签名,您可能会遇到此问题。您可以尝试在您最喜欢的 ZIP 编辑器中打开 .jar,然后从 META-INF 中删除文件,直到您只剩下您的 MANIFEST.MF。但是,一般不建议这样做。 (无效签名可能是由于有人将恶意软件注入到原始签名的 JAR 文件中。如果您删除了无效签名,您就是在用恶意软件感染您的应用程序!)推荐的方法是获取具有有效的 JAR 文件签名,或从(真实的)原始源代码重建它们。

      最后,如果MANIFEST.MF 文件中存在语法错误(请参阅https://stackoverflow.com/a/67145190/139985),您显然会遇到此问题。


      java 的替代语法

      使用java command 启动Java 程序有三种替代语法。

      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> ...]
        

        入口点类的名称要么由&lt;module&gt; 本身定义,要么由可选的&lt;mainclass&gt; 给出。

      3. 从 Java 11 开始,您可以使用 java 命令使用以下语法编译和运行单个源代码文件:

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

        其中&lt;sourcefile&gt;(通常)是一个后缀为“.java”的文件。

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


        IDE

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

        但是,如果您在 IDE 背后执行操作,则仍有可能发生此异常。例如,如果您之前在 Eclipse 中为您的 Java 应用程序设置了应用程序启动器,然后您将包含“main”类的 JAR 文件移动到文件系统中的不同位置不告诉 Eclipse,Eclipse 会无意中使用不正确的类路径启动 JVM。

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

        IDE 也可能会简单地感到困惑。 IDE 是非常复杂的软件,包含许多交互部分。其中许多部分采用各种缓存策略,以使 IDE 作为一个整体响应。这些有时会出错,一个可能的症状是启动应用程序时出现问题。如果您怀疑这可能会发生,那么值得尝试其他方法,例如重新启动 IDE、重建项目等等。


        其他参考

【讨论】:

  • 当我尝试使用 3rd 方库运行 Class 时遇到了这个问题。我这样调用java:java -cp ../third-party-library.jar com.my.package.MyClass;这不起作用,而是需要将本地文件夹也添加到类路径(由:分隔,如下所示:java -cp ../third-party-library.jar:. com.my.package.MyClass,那么它应该可以工作
  • 经过多年的 java 编程,我仍然设法结束了这个页面。对我来说,问题是the classpath syntax is OS-dependent。我对在 Windows 上编程有点陌生,不知道。
  • 补充说明,第2点救救我!很遗憾看到java 并没有说它没有找到导入的类,而是说你试图运行的主类。这是一种误导,尽管我确信这是有原因的。我遇到了java 确切知道我的班级在哪里的情况,但是它找不到导入的班级之一。它没有这么说,而是抱怨找不到我的主要课程。真的,很烦。
  • 我在 Eclipse 中遇到过两次这个问题。第一次 main() 的签名是错误的。第二次我重命名了一个 .jar,即使我将新的添加到构建路径中,Eclipse 也没有找到旧的,所以项目没有编译,出现这个错误。我必须从 Project > Properties > Java Build Path > Libraries 中删除 .jar 文件。
  • 我已经第三次遇到了。我从 Windows 10 批处理文件运行程序,并将 .jar 名称放入变量中(使用“-cp %jarname%;lib*”调用)。我错误地在 jarname 的末尾添加了一个额外的空格,这导致了错误。帽子戏法 :)
【解决方案2】:

如果您的源代码名称是 HelloWorld.java,那么您的编译代码将为 HelloWorld.class

如果您使用以下方法调用它,您将收到该错误:

java HelloWorld.class

相反,使用这个:

java HelloWorld

【讨论】:

  • 问题是这个解决方案只适用于在默认包中声明的没有 JAR 文件依赖关系的 Java 类。 (即便如此,也并非总是如此。)大多数 Java 程序并不是那么简单。
  • 就像斯蒂芬说的那样,这只适用于“默认包”——这意味着文件顶部的包声明。为了快速测试一些代码,我做了:javac TestCode.java,然后是java TestCode
  • 这对我不起作用。它仍然说,“无法找到或加载主类 HelloWorld”
  • 我需要做java -classpath . HelloWorld
  • @ChrisPrince - 是的......这有效......有时。要了解它何时有效,何时无效,请阅读投票最多的答案。
【解决方案3】:

如果您的课程在包中那么你必须 cd 到你的项目的根目录并使用类的完全限定名 (packageName.MainClassName) 运行。

例子:

我的课在这里:

D:projectcomcse

我的主类的完全限定名称是:

com.cse.Main

于是我cd回到项目根目录:

D:project

然后发出java 命令:

java com.cse.Main

这个答案是为了将新手 Java 程序员从一个常见错误造成的挫折中解救出来。我建议您阅读接受的答案,以更深入地了解 Java 类路径。

【讨论】:

  • 这个答案提出了一大堆假设。还有其他方法可以实现这一目标。我建议人们不要盲目地遵循上述建议,而是花时间阅读我的答案中解释 Java 类路径如何工作的链接。最好了解你在做什么......
  • 这个答案做出了我需要的确切假设:) 我位于 .class 文件的目录中,而 java.exe 没有工作。一旦我在上面 cd-ed 并使用命令行中包含的包名称运行它就可以了。
  • 我同意尼克康斯坦丁的观点。同样在这里。这是一个遵循我所做步骤的确切示例,它也对我有用。 java 类路径处理有一定的逻辑,但我肯定不会那样设计它。
  • 谢谢,你的回答帮助我看看我用大写的 Main_
  • 我在尝试这个之后写了这个评论,但它没有用。我有一个名为 Helloworld 的项目,它只包含 1 个 java 文件 Helloworld/src/com/firstpackage/Test.java (windows 10.intellij idea)。我不有 CLASSPATH 环境变量,我想专门为这个项目设置类路径。在 Helloworld 目录中运行 java com.firstpackage.Test 不起作用,命令 java -classpath C:UsersmatuagkeetarpIdeaProjectsHelloworldsrccomirst‌​package Test.java 也没有设置类路径变量。你能帮我吗?
【解决方案4】:

使用关键字“包”

如果您的源代码中有package 关键字(主类定义在一个包中),您应该使用类的全名 (packageName.MainClassName) 在分层目录上运行它。

假设有一个源代码文件(Main.java):

package com.test;

public class Main {

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

要运行此代码,您应该将 Main.Class 放在 package like 目录中:

C:Usersworkspace estappcom estMain.Java

然后将终端的当前目录更改为项目的根目录:

cd C:Usersworkspace	estapp

最后,运行代码:

java com.test.Main

没有关键字“包”

如果您的源代码名称上没有任何包,则可能是您输入了错误的命令。假设你的Java文件名是Main.java,编译后:

javac Main.java

你的编译代码将是Main.class

如果您使用以下方法调用它,您将收到该错误:

java Main.class

相反,使用这个:

java Main

【讨论】:

  • 请参阅我的答案的“附加说明 #1”。为了更好地解释这个问题。
  • @StephenC 是的,您的答案更完整(当然,+1),但是这个特定的答案中有“包”这个词,这让我可以快速找到我需要的东西。它奏效了。所以+1拉扎维。 StephenC,您的缺少我需要的简单包示例,因为我是 Java 新手。
  • 这正是我的问题。我一直在阅读大量的 Java 文档,而这个具体的例子正是我所需要的
  • 是的,具体的例子很好,这很好。我敢肯定,主要答案是非常彻底的,但是很难看到森林中的树。不错的@Razavi
  • 我喜欢这个简短而有用的答案,而不是接受的答案!
【解决方案5】:

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

javac HelloWorld.java
java -cp . HelloWorld

【讨论】:

  • 这不是一个好的建议。您取决于未设置的 CLASSPATH 环境变量,或者具有与“。”一致的值。是的,它在许多情况下都有效,但在其他情况下则无效。
  • 当然javac -classpath . HelloWorld.java 会起作用的!在您的情况下,这是一个更好的解决方案。
  • 如果您将“package com.some.address”作为第一行 - 这将不起作用。您需要注释掉“包裹地址”..
  • @Joe - hack(注释掉包)会起作用(在某些情况下),但这是一个坏主意。一个更好的想法是学习/理解导致问题的原因并实施正确的解决方案。
  • 取消设置类路径变量基本上对我有用。
【解决方案6】:

在命令行上指定类路径对我有帮助。例如:

  1. 创建一个新文件夹,C: emp

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

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

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

     java -classpath C:	emp Temp Hello!
    

【讨论】:

  • 在 Ubuntu 中,我还必须指定路径。不明白为什么默认情况下它不能使用当前工作目录。我确信 Java 是由键盘制造商赞助的!!
  • @gone - “。”的原因默认情况下不在 $PATH 中,这是一个安全陷阱。 seas.upenn.edu/cets/answers/dot-path.html
  • 非常感谢......即使不知道为什么即使在环境变量中设置了类路径,java 也无法找到它。
  • @akash89 - 最可能的原因是:1) java 没有查看 $CLASSPATH(因为您使用了 -classpath 或 -jar)或 2) 未在未设置的环境中设置类路径设置有效在运行java 的上下文中;例如因为您没有在正确的 shell 中“获取”添加 setenv 命令的文件。
  • 我仍然得到错误:找不到或加载主类 Temp 任何人都可以帮忙!
【解决方案7】:

根据报错信息(“Could not find or load main class”),有两类问题:

  1. 主类不能成立
  2. 主类不能加载(在接受的答案中没有充分讨论这种情况)

    主类不能成立当有完全限定类名中的拼写错误或语法错误或者它提供的类路径中不存在.

    主类不能加载什么时候课程无法启动.通常主类扩展另一个类,并且该类不存在于提供的类路径中。

    例如:

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

    如果不包含camel-spring,会报这个错误。

【讨论】:

  • “基本上”还有很多其他类别。缺少超类问题是一个非常不寻常的子案例。 (如此不寻常,我从未见过它......在这个网站上提出的问题中。)
  • 有两个,因为错误显示“无法查找或加载主类”。如果还有其他类别,请告诉我。我已经看过了,所以只想在这里分享它,也许其他人会需要它。
  • 我会将其修改为“您需要包含启动主类所需的所有类以避免此特定错误”。我不是想说服你。这只是我想看到的一种方式。我把答案留在这里只是为了那些可能喜欢以这种方式阅读内容的人。让我们不要进一步扩展这个讨论:) 我将我的声明更改为“在接受的答案中没有完全讨论”,希望你感觉更好。
  • 此信息至关重要,值得明确提及(这是唯一提及 extends 的答案)。我刚刚学会了当主课失败时的艰难方法加载因为它扩展了另一个不可能成立, 爪哇不报告未找到哪个实际类(不像NoClassDefFoundError)。所以是的,它确实发生了,当你不知道这一点时,这是一个令人毛骨悚然的情况。
  • 在这种情况下,有什么方法可以准确判断哪个依赖类无法加载?
【解决方案8】:

使用这个命令:

java -cp . [PACKAGE.]CLASSNAME

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

java -cp . Hello

如果您的文件 Hello.java 在包 com.demo 中,则使用以下命令

java -cp . com.demo.Hello

在 JDK 8 中,类文件经常出现在同一个文件夹中,但 java 命令需要类路径,因此我们添加-cp .将当前文件夹作为类路径的参考。

【讨论】:

  • 这仅适用于简单的情况。更复杂的情况需要更复杂的类路径。
  • 而对于 >>really<< 简单的情况,-cp . 是不必要的,因为如果 $CLASSPATH 未设置,那么 . 是默认的类路径。
  • 没有斯蒂芬,很多时候在 Windows 默认类路径中不起作用。我在三台不同的机器上试过,你也可以试试。
  • 这可能是因为您实际上在某处设置了 %CLASSPATH% 环境变量。如果你这样做,那么你没有使用默认的类路径。 (echo %CLASSPATH% 输出什么?)不,我无法检查,因为我没有 Windows PC。
  • 当我尝试从命令行运行一个简单的程序时,这对我有用
【解决方案9】:

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

java -cp lib.jar com.mypackage.Main

它适用于 Windows 的 ; 和 Unix 的 :

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

【讨论】:

  • 是的。这很可能是因为您的 Main 不在 JAR 文件中。 -cp lib.jar;-cp lib.jar;. 的含义相同,即当前目录包含在类路径中。
  • 终于解决了unix的问题..谢谢(与:)一起使用
【解决方案10】:

尝试-Xdiag.

Steve C's answer 很好地涵盖了可能的情况,但有时确定类是否不能成立或者加载可能没那么容易。使用 java -Xdiag(从 JDK 7 开始)。这会打印出一个很好的堆栈跟踪,它提供了消息Could not find or load main class 消息含义的提示。

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

【讨论】:

    【解决方案11】:

    有时可能导致问题的原因与主要课程无关,我不得不以艰难的方式找出这一点。这是我移动的一个引用库,它给了我:

    无法找到或加载主类 xxx Linux

    我刚刚删除了该引用,再次添加它,它再次正常工作。

    【讨论】:

    • 听起来问题是由于您的 IDE 项目中的“引用”损坏,您的类路径不正确。我将更新我的答案以涵盖该案例。
    • @StephenC 和 EduardoDennis,这里也缺少一个 jar,该 jar 包含一个接口,主类依赖于该接口被实例化。所以,错误信息太宽泛了。如果找不到类文件,我应该说“找不到”,如果缺少其他东西但不是文件本身,我应该说“无法加载(缺少依赖项)”,所以如果你只关注,错误消息太宽泛会误导在它的“查找”部分:(
    • @AquariusPower - 对于“原因”异常,应该有一个额外的“由”堆栈跟踪,表示缺少类。如果您想向 Java 开发人员建议他们更改 20 多年以来一直在说的错误消息......请随意。 (我认为错误消息是正确的。问题是 >>you<< 缩小了错误的子句。)
    • @StephenC 我的意思是,如果主类文件可用或不可用,他们肯定可以访问这些信息,所以为什么不向我们显示一个更好的错误消息,说明此类文件丢失。另一方面,他们也可以说“找到了文件但无法加载”,我们会及时关注依赖关系,而不是浪费半天时间研究和测试来理解。只是我的意思是:)。他们可能会在 20 多年内以有限的方式做到这一点,但他们可以改进它,我们在这里通过我们的批评和投诉来保证这将发生! :D
    • 请理解>>我<<的意思。在对 3 岁问答的一些晦涩评论中抱怨它不会有任何效果。可能对您的投诉采取行动的人不会注意到它。如果您想做一些建设性的事情,请提交补丁。 (我不评价你的机会,但它们会比你抱怨它的机会更大。)
    【解决方案12】:

    我有同样的问题,终于找到了我的错误:) 我使用此命令进行编译并且它工作正常:

    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
    

    【讨论】:

      【解决方案13】:

      在这种情况下,您有:

      无法找到或加载主类?类路径

      这是因为您使用的是“-classpath”,但破折号与命令提示符下java 使用的破折号不同。我在从Notepad 复制和粘贴到 cmd 时遇到了这个问题。

      【讨论】:

      • 哇!这是一个完全奇怪的原因! (但它适合您使用记事本而不是真正的文本编辑器:-))
      【解决方案14】:

      如果您使用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>
      

      【讨论】:

        【解决方案15】:

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

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

        【讨论】:

        • 是的。请参阅我的示例 #2 指定类名的错误方法!!
        【解决方案16】:

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

        我是这样编译的:

        javac HelloWorld.java
        

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

        java Helloworld.java
        

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

        【讨论】:

        • 这是因为您正在执行 .java 的编译版本。它实际上是在执行 .class 文件
        • 作为记录,这与我的答案中的原因#1,示例#5相同......
        【解决方案17】:

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

        这是相应的Mac命令:

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

        在此示例中,包是com.test,并且lib 文件夹也将包含在类路径中。

        【讨论】:

        • 在 Linux 上就像在 Mac 上一样。
        • 为什么需要/*
        • 它是一种通配符语法。 (这不是强制性的。如果您愿意,可以显式列出 JAR。)
        【解决方案18】:

        类文件位置:C:estcom公司

        文件名:主类

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

        命令行命令:

        java  -classpath "C:	est" com.company.Main
        

        请注意,类路径确实不是包括公司.

        【讨论】:

          【解决方案19】:

          我以为我以某种方式错误地设置了我的类路径,但问题是我输入了:

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

          代替:

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

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

          【讨论】:

          • 我已经更新了我的答案,试图解决这种困惑。
          • 这些都不正确。该类必须以utilities.myapp.Cool 或任何其包名称(如果有)的形式给出。
          【解决方案20】:

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

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

          您也可以使用 set CLASSPATH=%CLASSPATH%;. 将其设置为“一次性”。只要您的 cmd 窗口打开,这将持续。

          【讨论】:

          • 这个建议可能有帮助,也可能没有帮助。如果类树包含当前目录中的类,这将有所帮助。如果他们不是,就不会。我实际上不会这样做。相反,我会创建一个单行包装脚本,无论用户是否在“正确”目录中都可以使用。
          【解决方案21】:

          在 Windows PowerShell 中宣传的使用 -cp 选项运行 java 时,您可能会收到类似于以下内容的错误:

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

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

          java -cp 'someDependency.jar;.' ClassName
          

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

          【讨论】:

            【解决方案22】:

            这是一个具体案例:

            Windows(使用Windows 7 测试)不接受类和包名称中的特殊字符(如á)。不过,Linux 确实如此。

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

            【讨论】:

              【解决方案23】:

              在我的情况下解决问题的是:

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

              打开类路径选项卡,单击先进的...按钮,然后添加bin 文件夹你的项目。

              【讨论】:

                【解决方案24】:

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

                set path="paste the set path address"
                

                然后你需要加载程序。在存储的驱动器中键入“cd(文件夹名称)”并编译它。例如,如果我的程序存储在 D 盘,输入“D:”按回车并输入“cd(文件夹名称)”。

                【讨论】:

                • 这无济于事。这个问题是关于 Java 程序,而不是普通的可执行文件。 Java 不使用 PATH 来定位任何东西,如果“cd”有帮助,那么它是靠运气而不是靠判断。
                • if "cd" helps then it by luck rather than by judgement。这是错误的(我相信),因为 java 默认使用当前目录 . 作为类路径的一部分。
                • @GKFX - 这就是我的意思。除非您知道您使用的是默认类路径(或带有“.”的类路径),否则“cd”将不起作用。这个解决方案更多地靠运气(即猜测/希望“。”在类路径上)而不是通过判断(即检查“。”在类路径上)。此外,您对默认值不正确。 Java 使用“.”默认情况下作为类路径,而不是默认情况下作为类路径的一部分。
                • 大概在Windows 上?
                【解决方案25】:

                在 Java 中,当您有时使用 Java 解释器可执行文件从命令行运行 JVM 并尝试使用 public static void main (PSVM) 从类文件启动程序时,即使 classpath 参数为JVM 是准确的,并且类文件存在于类路径中:

                错误:找不到或未加载主类

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

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

                【讨论】:

                • 你读过接受的答案吗?你的回答有没有增加什么新东西?
                • @StephenC 我试图通过查看“原因”类别及其要点在您的列表中找到原因。我在“原因 #1”和“原因 #2”标题中找不到匹配点,这与我的情况并不接近(因为我确信类路径本身没有问题)。我通过实验找到了原因,我很惊讶在我的例子中显示“找不到主类”错误,因为实现接口不在类路径上。当然,您可以说“您应该阅读帖子中描述的所有内容”,但在我看来,您的理由清单可以改进。
                • 链接坏了:“嗯。我们找不到那个站点。我们无法连接到 www.computingnotes.net 上的服务器。”
                【解决方案26】:

                您确实需要从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
                

                【讨论】:

                • 一个类不能称为“CommandLine.class”。那将是一个 Java 语法错误。 (您的意思是包含已编译类的文件称为“CommandLine.class”...)。另一个问题是,“cd 到源目录”的指令只有在将代码 >> 编译到 << 源目录树时才有效。最后,如果您的编译使用了“-cp”参数,那么您在运行时需要一个等效参数。
                • 在我的项目中,我在根目录中有 src 文件夹和 bin 文件夹。我必须将cd 转换为src,然后运行对我有用的命令java ../bin com.blah.blah.MyClass。所以谢谢你的提示!
                【解决方案27】:

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

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

                /dir1/dir2/dir3/myjar.jar中的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。当用户 1 可以看到文件并且可以访问它们时,它可能会让某人发疯,但是用户 2 仍然会发生错误。

                【讨论】:

                  【解决方案28】:

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

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

                  编译:

                  javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
                  
                  • -cp- 类路径参数;一个一个地传递所有依赖的 JAR 文件
                  • *.java - 这是具有 main 方法的 Java 类文件。 sdsd

                  跑:

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

                  【讨论】:

                  • 这一切都假设 1)JavaMongoDBConnection 没有包,并且 2)您不更改目录。至少可以说,它是脆弱的。而且通过不解释问题,它将引导新手尝试这种方法在它不起作用的情况下.简而言之,它鼓励“巫毒编程技术”:en.wikipedia.org/wiki/Voodoo_programming
                  【解决方案29】:

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

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

                  【讨论】:

                  • 删除 main 方法不会解决问题。具有多个入口点的应用程序在技术上没有任何问题。
                  【解决方案30】:

                  有时,在您可能尝试过的某些在线编译器中,如果您不写public class [Classname] 而只写class [Classname],则会出现此错误。

                  【讨论】:

                  • 请提供(冒犯编译器的)示例。虽然创建“入口点”类public 是常规/正常的,但Java 规范不需要这样做,标准的Oracle / OpenJDK java 命令也不需要。
                  猜你喜欢
                  • 2021-09-19
                  相关资源
                  最近更新 更多