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

Posted

技术标签:

【中文标题】“找不到或加载主类”是啥意思?【英文标题】:What does "Could not find or load main class" mean?“找不到或加载主类”是什么意思? 【发布时间】:2022-01-23 09:24:59 【问题描述】:

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

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

【问题讨论】:

请注意,这是一个“自我回答”问题,旨在为新 Java 用户提供通用参考问答。我找不到足以涵盖此问题的现有问答(IMO)。 【参考方案1】:

修复它的最简单方法是在此处重新下载 maven apache:https://maven.apache.org/download.cgi

比你再次设置你的路径

系统变量

将您设置 apache maven 文件夹的路径放在那里,例如:C:\Program Files\apache-maven-3.8.4\bin

重新启动终端或 IDE,应该可以工作了。

它总是对我有用。

【讨论】:

如果你没有运行 maven 项目,请尝试检查你的 java PATH,有时如果没有设置 java 路径,你的程序将无法运行,因为找不到主类。【参考方案2】:

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

which(令人困惑)看起来像一个文件路径名,但不是一个。请注意,完全限定名称这个术语是标准的 Java 术语......不是我只是为了让你感到困惑而编造的 :-)

下面是java 命令的示例:

    java -Xmx100m com.acme.example.ListUsers fred joe bert

以上将导致java 命令执行以下操作:

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

Java 找不到类的原因

当您收到消息“Could not find or load main class ...”时,表示第一步失败。 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

示例 #3 - 大小写错误的类名:

java com.acme.example.listuser

示例 #4 - 一个错字

java com.acme.example.mistuser

示例 #5 - 源文件名(Java 11 或更高版本除外;见下文)

java ListUser.java

示例 #6 - 你完全忘记了类名

java lots of arguments

原因 #2 - 应用程序的类路径指定错误

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

The java command documentation Setting the Classpath。 Java 教程 - PATH and CLASSPATH

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

    阅读上面链接的三个文档。 (是的...阅读它们!Java 程序员了解至少 Java 类路径机制如何工作的基础知识是很重要的。) 查看命令行和/或运行java 命令时生效的CLASSPATH 环境变量。检查目录名和 JAR 文件名是否正确。 如果类路径中有相对路径名,请检查它们是否正确解析...从运行java 命令时生效的当前目录。 检查类(在错误消息中提到)是否可以位于有效的类路径中。 请注意,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需要找到:

类本身。 超类层次结构中的所有类和接口(例如,参见Java class is present in classpath but startup fails with Error: Could not find or load main class) 通过变量或变量声明、方法调用或字段访问表达式引用的所有类和接口。

(注意: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://***.com/a/67145190/139985)。


java 的替代语法

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

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

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

    例如

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

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

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

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

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

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

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

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

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


集成开发环境

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

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

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

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


其他参考

来自 Oracle Java 教程 - Common Problems (and Their Solutions)

【讨论】:

我在尝试使用 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 的末尾添加了一个额外的空格,这导致了错误。帽子戏法:)【参考方案3】:

我升了一级。所以,现在 HelloWorld.class 文件位于 hello\HelloWorld.class 并在命令下方运行。其中 cp 是类路径,而 .表示仅检查当前目录。

java -cp . hello.HelloWorld

输出

Hello world!

【讨论】:

【参考方案4】:

带包

如果你的源代码中有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 放在 package like 目录中:

C:\Users\workspace\testapp\com\test\Main.Java

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

cd C:\Users\workspace\testapp  

最后,运行代码:

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】:

我尝试在 onlinegdb 编译器上执行这个用 intellij idea 编写的代码时遇到了这个错误。

对我来说,注释掉这一行有助于我避免这个错误。

//package com.company;

【讨论】:

想解释一下为什么会修复它? 是的,所以基本上我试图在 com.company 包之外运行 java 代码,所以通过评论这部分它被禁用,我也能够在在线 gdb 中运行它 如果你必须这样做才能让它工作,在线 Gdb 基本上是残废的。 期待更好的解释【参考方案6】:

排除以下文件解决了问题。

META-INF/*.SF

META-INF/*.DSA

META-INF/*.RSA

build.gradle中添加如下代码

jar 
    from 
        configurations.compile.collect  it.isDirectory() ? it : zipTree(it) 
    
    
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    
    manifest 
        attributes(
                'Main-Class': 'mainclass'
        )
    

【讨论】:

为什么解决了这个问题?你到底在这里做什么?如果您正在修改已签名的 JAR 文件,这看起来像是一种黑客行为。请解释您实际在做什么......以便人们可以决定您的“这对我有用”的解决方案是否与他们正在做的事情相关。【参考方案7】:

这就是我解决问题的方法。

我注意到如果您在编译中包含 jar 文件,将当前目录 (./) 添加到类路径会有所帮助。

javac -cp "abc.jar;efg.jar" MyClass.java java -cp "abc.jar;efg.jar" MyClass VS javac -cp "./;abc.jar;efg.jar" MyClass.java java -cp "./;abc.jar;efg.jar" MyClass

【讨论】:

这应该是零差异。这两种形式都是有效的 Java,它们是等价的。 我会编辑,类路径“./”,最大的不同。 嗯,是的。不正确的类路径是接受答案的原因 #2。请注意,您的特定修复仅在某些情况下有效。 (例如,它不适用于 MacOS 或 Linux。)【参考方案8】:

原因 #2 - 应用程序的类路径指定不正确 阅读上面链接的三个文档。 (是的......阅读它们!重要的是,Java 程序员至少要了解 Java 类路径机制如何工作的基础知识。)我想将此文档添加到上面 JDK 工具和实用程序一般一般信息(文件结构、类路径、如何找到类、更改)增强(JDK 7 中的增强)标准 JDK 工具和实用程序https://docs.oracle.com/javase/7/docs/technotes/tools/index.html https://docs.oracle.com/javase/7/docs/technotes/tools/findingclasses.htmlhttps://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.htmlJava 启动器如何查找类了解类路径和包名https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

Java 中的类加载器 Java 类加载器是 Java 运行时环境的一部分,它将 Java 类动态加载到 Java 虚拟机中。由于类加载器,Java 运行时系统不需要了解文件和文件系统。 Java 类不会一次全部加载到内存中,而是在应用程序需要时加载。此时,JRE 调用 Java ClassLoader,这些 ClassLoader 将类动态加载到内存中。 https://en.wikipedia.org/wiki/Java_Classloaderhttps://www.geeksforgeeks.org/classloader-in-java/https://en.wikipedia.org/wiki/Java_virtual_machine

【讨论】:

谢谢,但不用了。类加载器层次结构的行为不太可能是读者问题的原因。如果您查看原因 #2,您会注意到它是为了鼓励读者去其他地方了解类路径和相关内容的解释。我做了一个深思熟虑和深思熟虑的决定。 (理想情况下,应该有另一个规范的问答来描述这些内容。另外,请注意,人们已经在抱怨我对这个问题的回答已经太长了。【参考方案9】: 在 Intellij 中检查您的全局库和本地库 在 pom.xml 中检查库版本,可能是旧库 上面提到的可能性太多了,需要尝试 太

【讨论】:

【参考方案10】:

[Java 版本:11]

如果您使用的是 Java 11,则无需编译和运行您的 java 文件。

就这样跑

Java ClassName.java

例子:

class abc 
    public static void main(String[] args)
        System.out.println("hello Jarvis ");    
    

现在运行命令

java abc.java

【讨论】:

1) 不回答问题。 2)“java的替代语法”替代#3。【参考方案11】:

场景:使用命令提示符(在 Windows 中为 CMD编译运行一个简单的“java”只有“Main.java”文件的程序,指定了“package main”。

源文件路径:

一些项目名称文件夹\src\main\Main.java

目标文件夹:

一些项目名称文件夹\dest

目标文件路径(文件夹 '\main' 和文件 '\Main.class' 将由 'javac' 生成):

一些项目名称文件夹\dest\main\Main.class

Main.java如下:

package main;

public class Main 
    public static void main(String[] args) 
        System.out.println("Hello world");
    

编译:

// 'javac' compiler will produce 'Main.class' in the 'dest\main' folder.
// 'main' folder is created because in the source file(in our case: 'Main.java') is
// specified 'package main'.

javac -d ./dest ./src/main/Main.java

运行编译后的文件(在我们的例子中:'Main.class'):

// '-cp'(is the same as '-classpath')
// './dest'(means destination folder, where resides compiled 'Main.class').
// 'main.Main'(means 'package' 'main', which contains class 'Main'('Main.class'))
// WARNING: when run 'java' class, MUST NOT type extension '.class'
//          after 'class name
//          (in our case: 'main.Main'(<package>.<class-name>) WITHOUT extension 
//           '.class').

java -cp ./dest main.Main

// Hello world

【讨论】:

和***.com/a/26587225/139985 说的一样(从 2014 年开始)【参考方案12】:

搜索了 2 天后,我找到了这个解决方案,并且它有效。这很奇怪,但对我有用。

package javaapplication3;
public class JavaApplication3 

/**
 * @param args the command line arguments
 */
public static void main(String[] args) 
    // TODO code application logic here
    System.out.println("Hello");

这是我要运行的程序,位于 C:\Java Projects\JavaApplication3\src\javaapplication3

现在在这个位置打开 cmd 并使用这个命令编译程序

javac JavaApplication3.java

编译后向下导航一个目录,即 C:\Java Projects\JavaApplication3\src

现在运行以下命令来执行程序

java javaapplication3.JavaApplication3

【讨论】:

如果这对你有用,那么你的源代码必须有一个 package javaapplication3; 声明,你没有包含在答案中。 @StephenC 哦,对不起,我将更新我的答案。 现在它和***.com/a/26587225/139985(从 2014 年开始)基本相同【参考方案13】:

另外一个让我摸不着头脑的场景是:

package com.me
Public class Awesome extends AwesomeLibObject 
    ....
    public static void main(String[] argv) 
         System.out.println("YESS0");
    

其中 AwesomeLibObject 是在外部库中定义的类。 我收到了同样令人困惑的错误消息:

Error: Could not find or load main class com.Awesome

解决方法很简单:外部库也必须在类路径中!

【讨论】:

原因 #2c - 不正确的类路径/缺少依赖项【参考方案14】:

如果您使用 IntelliJ 并在从 IDE 运行 main 方法时遇到错误,只需确保您的类位于 java 包中,而不是位于 kotlin

【讨论】:

【参考方案15】:

我在 IntelliJ 中创建的演示程序遇到了这个问题。

有两个关键点来解决:

    程序的包名 终端/cmd提示符的当前工作目录

我的演示程序:

package io.rlx.tij.c2;

public class Ex10 
    public static void main(String[] args) 
        // do something
    

源码路径:

../projectRoot/src/main/java/io/rlx/tij/c2/Ex10.java
    转到java 目录:cd ../projectRoot/src/main/java 编译到类:javac ./io/rlx/tij/c2/Ex10.java 运行程序:java io.rlx.tij.c2.Ex10

如果我在../projectRoot/src/main/java/io/rlx/tij/c2 中运行程序或者我在没有包名的情况下运行它,我会得到这个错误:Error: Could not find or load main class

【讨论】:

和***.com/a/26587225/139985 说的一样(从 2014 年开始)【参考方案16】:

还有一个问题让我花费了一些时间:命令行类路径参数的行为与您预期的不同。我在 MacOS 上直接调用 CLI,并且在调用中包含了两个 jar。

例如,这两个都使工具混淆了主类的名称:

这是因为星号导致它无法正确解析 args:

java -cp path/to/jars/* com.mypackage.Main

这个是因为 -- 我不知道为什么:

java -cp "*.jar" com.mypackage.Main

这行得通:

java -cp "path/to/jars/*" com.mypackage.Main

明确列出这两个罐子也有效:

java -cp path/to/jars/jar1.jar:path/to/jars/jar2.jar com.mypackage.Main

【讨论】:

“我不知道为什么” - 因为 * 被 shell 扩展为一个 JAR 文件名列表用空格分隔 ...除非用引号括起来。这是标准的 UNIX shell 东西。至于其余的:都在java 手册条目中,包括使用: 和通配符语法("path/to/jars/*")。 那是“不确定为什么“*.jar”不起作用”。第一个更清楚,因为外壳在弄乱它。 第二个不起作用,因为java 命令不理解该通配符。 java 手册解释了它所理解的内容。【参考方案17】:

我有一个奇怪的:

错误:无法找到或加载主类 mypackage.App

原来我在项目的pom.xml 文件中编码了对POM(父级)的引用(我的项目的pom.xml 指向父级pom.xml)并且relativePath 关闭/错误.

以下是我项目的pom.xml 文件的一部分:

<parent>
    <groupId>myGroupId</groupId>
    <artifactId>pom-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../badPathHere/pom.xml</relativePath>
</parent>

一旦我解决了 POM relativePath,错误就消失了。

去看看。

【讨论】:

【参考方案18】:

就我而言,我只是在 Eclipse 中更改 JRE。

请查看随附的屏幕截图:

【讨论】:

【参考方案19】:

关于外部库的回答 -

编译:

javac -cp ./<external lib jar>: <program-name>.java

执行:

java -cp ./<external lib jar>: <program-name>

上述方案在 OS X 和 Linux 系统中运行良好。注意类路径中的:

【讨论】:

【参考方案20】:

如果此问题与 Eclipse 相关:

尝试将项目添加到您的类路径。

见下图:

这个方法对我有用。

【讨论】:

【参考方案21】:

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

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

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

拥有 JAR 文件的用户 1 可以这样做:

# 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 仍然会发生错误。

【讨论】:

【参考方案22】:

右键单击项目。

    选择“打开模块设置” 将src 文件夹标记为“来源” 去编辑配置,然后选择你的主类 单击确定应用按钮

这对我有用。

【讨论】:

【参考方案23】:

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

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

【讨论】:

【参考方案24】:

如果是Maven 项目

    转到 POM 文件。 删除所有依赖项。 保存 POM 文件。 再次只导入必要的依赖项。 保存 POM 文件。

问题应该会消失。

【讨论】:

【参考方案25】:

这也发生在我身上。在我的情况下,它只发生在源代码中存在HttpServlet 类时(IntelliJ IDEA 没有给出编译时错误;servlet 包被导入就好了,但是在运行时有这个main class 错误) .

我设法解决了。我去了菜单文件项目结构...

然后到模块

在 servlet 模块附近有一个 Provided 范围。我把它改成了编译

它成功了!

【讨论】:

【参考方案26】:

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

例子:

我的课程在这里:

D:\project\com\cse\

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

com.cse.Main

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

D:\project

然后发出java 命令:

java com.cse.Main

这个答案是为了让新手 java 程序员摆脱一个常见错误造成的挫败感,我建议你阅读接受的答案,以更深入地了解 java 类路径。

【讨论】:

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

我花了相当多的时间试图解决这个问题。我以为我以某种方式错误地设置了我的类路径,但问题是我输入了:

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

代替:

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

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

【讨论】:

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

使用这个命令:

java -cp . [PACKAGE.]CLASSNAME

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

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。 当我尝试从命令行运行一个简单的程序时,这对我有用【参考方案29】:

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

我是这样编译的:

javac HelloWorld.java

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

java Helloworld.java

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

【讨论】:

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

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

【讨论】:

以上是关于“找不到或加载主类”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

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

通过 jpackage 打包找不到或加载主类

Spring Boot gradle“找不到或加载主类”

Java JAR:找不到或加载主类

openmpi + java,找不到或加载主类

IntelliJ 构建错误的 JAR:找不到或加载主类