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

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

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

4000594 次浏览

java <class-name>命令语法

首先,您需要了解使用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命令执行以下操作:

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

Java找不到班级的原因

当您收到消息“无法找到或加载主类…”时,这意味着第一步失败了。java命令无法找到该类。事实上,消息中的“…”将是java正在寻找的完全限定类名

那么为什么它可能找不到类呢?

原因#1-你在类名参数上犯了一个错误

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

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

    java ListUser

    当类在包中声明时,例如com.acme.example,那么您必须使用完整的类名包括java命令中的包名;例如:

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

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

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

    java com.acme.example.mistuser
  • 示例#5-源文件名(Java11或更高版本除外;见下文)

    java ListUser.java
  • 示例#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/class”在类路径上,那么当JVM查找名为com.acme.example.Foon的类时,它将查找具有此路径名的“. class”文件:

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

如果您在类路径上放置了“/usr/Local/acme/class/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 neededjava Foon
# wrong, there is no `com/acme/example` folder in the current working directoryjava com.acme.example.Foon
# wrong, similar to abovejava -classpath . com.acme.example.Foon
# fine; relative classpath setjava -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath setjava -classpath /usr/local/acme/classes com.acme.example.Foon

备注:

  • 在大多数Java版本中,-classpath选项可以缩短为-cp。请检查相应的手册条目中的javajavac等。
  • 在类路径中选择绝对路径名和相对路径名时要仔细考虑。请记住,如果当前目录发生变化,相对路径名可能会“中断”。

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

类路径需要包含应用程序所依赖的所有其他(非系统)类。(系统类是自动定位的,你很少需要关心这一点。)为了正确加载主类,JVM需要找到:

(注意:JLS和JVM规范允许JVM“延迟”加载类,这可能会影响抛出类加载器异常的时间。)

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

偶尔会发生有人将源代码文件放入如果你在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> ...]

    e. g.

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

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

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

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

    入口点类的名称要么由<module>本身定义,要么由可选的<mainclass>给出。

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

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

    其中<sourcefile>(通常)是后缀为“. java”的文件。

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


IDE

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

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

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

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


其他参考资料

有时可能导致问题的原因与主类无关,我必须通过艰难的方式找到这一点。这是我移动的一个引用库,它给了我:

找不到或加载主类xxxLinux

我只是删除了那个引用,又添加了它,它又工作得很好。

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

set path="paste the set path address"

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

在我的情况下,出现错误是因为我提供了源文件名而不是类名。

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

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

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

java HelloWorld.class

相反,使用这个:

java HelloWorld

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

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

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

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

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

     java -classpath C:\temp Temp Hello!

使用关键字“包”

如果您的源代码中有#0关键字(主类在包中定义),您应该使用类的全名(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:\用户\工作空间\测试应用程序\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

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

示例:

我的课程在这里:

D:\project\com\cse\

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

com.cse.Main

所以我cd回到根目录:

D:\project

然后发出java命令:

java com.cse.Main

这个答案是为了将新手Java程序员从一个常见错误引起的挫败感中解救出来。我建议您阅读已接受的答案,以获得有关Java类路径的更深入的知识。

在这种情况下,你有:

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

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

当相同的代码在一台PC上运行,但在另一台PC上显示错误时,我找到的最好的解决方案是像下面这样编译:

javac HelloWorld.javajava -cp . HelloWorld

我以为我在某种程度上设置了错误的类路径,但问题是我键入了:

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

而不是:

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

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

根据错误消息(“无法找到或加载主类”),有两类问题:

  1. 主类不能是发现
  2. Main类不能是加载(在接受的答案中没有完全讨论这种情况)

当有完全限定类名中的拼写错误或语法错误在提供的类路径中不存在时,Main类不能是发现

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

例如:

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

如果不包括驼峰弹簧,则会报告此错误。

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

错误:未找到或加载主类

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

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

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

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

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

我在做了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" />

这是一个具体的案例:

Windows(用Windows7测试)不接受类和包名中的特殊字符(如á)。不过Linux可以。

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

解决我的问题的方法是:

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

打开类路径选项卡,单击高级…按钮,然后添加项目的#0文件夹

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

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

您确实需要从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]: thisargs[1]: isargs[2]: aargs[3]: commandargs[4]: lineargs[5]: 200args[6]: -100

试试-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

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

以下是相应的Mac命令:

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

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

对于数据库连接,我得到了这个。我只是在类路径中添加了以下内容:

export CLASSPATH=<path>/db2jcc4.jar:**./**

在这里,我最后附加了。/,以便在加载时也识别我的类。

现在只需运行:

java ConnectionExample <args>

它工作得很好。

似乎当我遇到这个问题时,它是独一无二的。

一旦我删除了文件顶部的包声明,它就工作得很好。

除此之外,似乎没有任何方法可以在我的机器上运行一个简单的HelloWorld.java,无论编译发生在哪个文件夹中,CLASSPATH或PATH,参数或从哪个文件夹调用。

使用此命令:

java -cp . [PACKAGE.]CLASSNAME

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

java -cp . Hello

如果你的文件Hello.java在包里面com.demo然后使用下面的命令

java -cp . com.demo.Hello

在JDK 8中,类文件经常出现在同一个文件夹中,但java命令需要类路径,因此我们添加#1以将当前文件夹作为类路径的引用。

在此输入图片描述

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

文件名:Main.class

完全限定类名:com.company.

命令行命令:

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

请注意,类路径没有包含\com\公司

默认情况下,Java使用当前工作目录.作为默认的CLASSPATH。这意味着当您在提示符下键入命令时,例如java MyClass,该命令被解释为您键入了java -cp . MyClass。您看到-cpMyClass之间的点了吗?(cp是较长的类路径选项的缩写)

这对于大多数情况来说已经足够了,并且在您尝试将目录添加到CLASSPATH之前,一切似乎都很好。在大多数情况下,当程序员需要这样做时,他们只需运行set CLASSPATH=path\to\some\dir这样的命令。此命令创建一个名为CLASSPATH的新环境变量,其值为path\to\some\dir,或者如果之前已经设置了CLASSPATH,则将其值替换为path\to\some\dir

完成后,你现在有一个CLASSPATH的环境变量,Java不再使用它的默认类路径(.),而是你设置的。所以第二天你打开编辑器,编写一些java程序,cd到你保存它的目录,编译它,并尝试使用命令java MyClass运行它,你会得到一个不错的输出:找不到或加载主类…(如果你的命令以前运行良好,现在得到这个输出,那么这可能是你的情况)。

发生的情况是,当您运行命令java MyClass时,Java在CLASSPATH中设置的目录中搜索名为MyClass的类文件,而不是您当前的工作目录,因此它找不到您的类文件。

你需要做的是再次将.添加到你的类路径中,这可以使用命令set CLASSPATH=%CLASSPATH%;.完成(注意分号后的点)。用简单的英语,这个命令说“选择最初CLASSPATH%CLASSPATH%)的值,将.添加到它(;.)并将结果分配回CLASSPATH”。

,您可以像往常一样使用命令java MyClass

在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正确处理类路径参数。

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

我是这样编译的:

javac HelloWorld.java

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

java Helloworld.java

当我删除.java并像java HelloWorld一样重写命令时,程序运行得很好。:)

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

有时,在一些你可能尝试过的在线编译器中,如果你不写public class [Classname]而只写class [Classname],你会得到这个错误。

在IDE开发的上下文中(Eclipse,NetBeans或其他),您必须将项目属性配置为具有主类,以便您的IDE知道当您点击“Play”时要执行的主类的位置。

  1. 右键单击您的项目,然后属性
  2. 转到运行类别并选择您的主类
  3. 点击运行按钮。

在此输入图片描述

在我的情况下,我得到了错误,因为我在Windows 7系统上混合了大写和小写包名称。将包名更改为所有小写解决了问题。另请注意,在这种情况下,我将. java文件编译为. class文件没有错误;它只是从同一个(sub-sub-sub-)目录运行的。

解决“无法加载主类错误”

在阅读了所有的答案后,我注意到大多数答案都不适合我。所以我做了一些研究,这是我得到的。只有在第一步不起作用的情况下才尝试这个。

  1. 尝试安装JRE 32或64。如果它不起作用,
  2. 打开转到C:\Program Files(x86)\JavaC:\程序文件\Java

    • 打开jdk文件夹,然后打开bin文件夹。
    • 复制路径并将其添加到环境变量中。确保用分号;分隔变量。例如,“C:\Yargato\bin; C:\java\bin;”。如果不这样做,会导致更多错误。

    • iii.转到jre文件夹并打开其bin文件夹。

    • 四。在这里搜索rt.jar档案。我的是:

      C:\Program Files(x86)\Java\jre1.8.0_73\lib\rt.jar复制并在环境变量下搜索类路径变量把它贴在那里。

    • v.现在重新启动cmd并再次尝试运行。错误将消失。
    • 六。我将发布一个链接到我的YouTube视频教程。

我在测试JavaMongoDB 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)

在我的例子中,我只是在Eclipse中更改JRE。

请查看附件的屏幕截图:

在此输入图片描述

我有一个奇怪的:

错误:无法找到或加载主类mypack. 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,错误就消失了。

想想吧。

关于外部图书馆的答案-

编译:

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

执行:

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

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

如果此问题与Eclipse相关:

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

请看下图:

在此输入图片描述

这个方法对我有效。

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

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

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

拥有JAR文件的User1可以这样做:

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

但它仍然不起作用:

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

这是因为正在运行的用户(User2)无权访问迪尔1、迪尔2、javalibs或迪尔3。当User1可以看到文件并可以访问它们时,它可能会让某人发疯,但User2仍然会发生错误。

右键单击该项目。

  1. 选择“打开模块设置”
  2. src文件夹标记为“源”
  3. 转到编辑配置,然后选择您的主类
  4. 点击好的申请按钮

这对我有用。

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

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

如果它是一个Maven项目

  1. 转到POM文件。
  2. 删除所有依赖项。
  3. 保存POM文件。
  4. 再次只导入必要的依赖项。
  5. 保存POM文件。

这个问题应该消失。

这也发生在我身上。在我的例子中,只有当源代码中存在HttpServlet类时才会发生这种情况(IntelliJ IDEA没有给出编译时错误;servlet包导入得很好,但是在运行时出现了这个main class错误)。

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

在此输入图片描述

然后到模块

在此输入图片描述

servlet模块附近有一个提供范围。我将其更改为编译

在此输入图片描述

它奏效了!

这是另一个花了我一点时间的问题:命令行类路径参数的行为不符合您的预期。我在MacOS上直接调用CLI,并且我在调用中包含了两个jar。

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

这是因为星号导致它错误地解析参数:

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

这是因为——我不知道为什么:

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

这奏效了:

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

显式列出两个jar也有效:

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

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

解决它有两个关键点:

  1. 程序的包名
  2. 终端/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
  1. 转到java dir:cd ../projectRoot/src/main/java
  2. 编译到class:javac ./io/rlx/tij/c2/Ex10.java
  3. 运行程序:java io.rlx.tij.c2.Ex10

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

如果您使用IntelliJ并在从IDE运行main方法时收到错误,请确保您的类位于java包中,而不是kotlin输入图片描述

还有一个场景让我挠头,我在这里没有找到任何参考,是:

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

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

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

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

经过2天的搜索,我找到了这个解决方案,这是有效的。这很奇怪,但它对我有效。

package javaapplication3;public class JavaApplication3 {
/*** @param args the command line arguments*/public static void main(String[] args) {// TODO code application logic hereSystem.out.println("Hello");}

}

这是我想运行的程序,位于C:\JavaProjects\JavaApplication ation3\src\javaApplication ation3

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

javac JavaApplication3.java

编译后向下导航一个目录,即C:\JavaProjects\JavaApplication ation3\src

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

java javaapplication3.JavaApplication3

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

源文件路径:

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

目标文件夹:

一些-项目-名称-文件夹\de st

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

//项目名称文件夹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

[Java版本:11]

如果你使用Java11,那么你不需要编译和运行你的java文件。

就像

Java ClassName.java

示例:

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

现在运行命令

java abc.java

输入图片描述

原因#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.html

https://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html

Java启动器如何查找类了解类路径和包名称

https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

JavaClassLoaderJavaClassLoader是Java运行时环境的一部分,它将Java类动态加载到Java虚拟机中。由于有了类加载器,Java运行时系统不需要了解文件和文件系统。

Java类不是一次加载到内存中,而是在应用程序需要时加载。此时,JRE调用JavaClassLoader,这些ClassLoader动态地将类加载到内存中。

https://en.wikipedia.org/wiki/Java_Classloader

https://www.geeksforgeeks.org/classloader-in-java/

https://en.wikipedia.org/wiki/Java_virtual_machine

在此输入图片描述

在此输入图片描述

在此输入图片描述

  • IntelliJ IDEA中,检查您的全球库*和地方图书馆
  • 检查库版本文件pom.xml,可能是旧库
  • 他们是这么多的可能性提到在前面的答案需要尝试过

我就是这样解决我的问题的。

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

javac -cp "abc.jar;efg.jar" MyClass.javajava -cp "abc.jar;efg.jar" MyClass

vs.

javac -cp "**./**;abc.jar;efg.jar" MyClass.java<br>java -cp "**./**;abc.jar;efg.jar" MyClass

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

META-INF/*. SF

META-INF/*.每日生活津贴

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')}}

我上了一级。所以,现在HelloWorld.class文件在你好\HelloWorld.class中,我运行了以下命令。其中cp是类路径,.表示仅检查当前目录。

java -cp . hello.HelloWorld

产出

Hello world!

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

你再一次设定你的道路:

在此输入图片描述

系统变量

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

在此输入图片描述

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

它总是为我工作。

这基本上意味着没有静态的main(String[] args)方法。它应该自动解析它。如果没有,当程序被制作时(它没有main方法)或当程序被打包时(不正确的清单信息),某些东西被搞砸了。

这招管用

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

这不管用

public class Hello {public Hello() {System.out.println("Hello");}}

如果你的包名是javatpoint,包名是com.javatpoint,类名是另一个,那么像这样编译你的类:

cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src\com\javatpointjavac AnotherOne.java

并使用

cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\srcjava com.javatpoint.AnotherOne

(此处应排除包名。)

Intellij IDE中选择run/debug>>edit configuration,然后选择正确的JDK用于构建和运行菜单。

对于Java的新版本,直到2022年都是Java18。您只需编写关键字和包含java扩展文件和分号的文件夹名称,如下所示:

package JavaProgramming;

因为我在JavaProgramming文件中有hello.java文件。注意:在为java编写文件夹名称时不要给出空格。像Java编程一样,你必须保持它像;程序设计,等等;

下面给出了一个简单的hello world的整个代码结构:

package JavaProgramming;
public class hello {public static void main(String[] args) {System.out.println("Hello java after long time");}}