“找不到或加载主类”是什么意思? 您所在的位置:网站首页 node啥意思 “找不到或加载主类”是什么意思?

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

#“找不到或加载主类”是什么意思?| 来源: 网络整理| 查看: 265

匿名用户

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

1的正常语法如下:

java [ ] [ ...]

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

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类的编译版本。 加载类。 检查类是否有一个main方法,该方法具有签名,返回类型和public static void main(string[])提供的修饰符。 (注意,方法参数的名称不是签名的一部分。) 调用该方法,将命令行参数(“fred”,“joe”,“bert”)作为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-a打字

java com.acme.example.mistuser

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

java ListUser.java

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

java lots of arguments

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

Java命令文档 设置类路径。 Java教程-路径和类路径

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

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

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

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

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

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

>

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

如果您试图通过移动类来重命名它,那也会失败。。。但是异常堆栈跟踪会有所不同。 可以这样说:

Caused by: java.lang.NoClassDefFoundError: (wrong name: )

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

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

要运行com.acme.example.foon类, 完整文件路径为/usr/local/acme//com/acme/example/foon.class, 您当前的工作目录是/usr/local/acme//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。 检查Java,javac等相应的手工条目。 在类路径中选择绝对路径名和相对路径名时要仔细考虑。 请记住,如果当前目录更改,相对路径名可能会“中断”。

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

类本身。 超类层次结构中的所有类和接口(例如,请参见Java类存在于类路径中,但启动失败,错误为:无法找到或加载主类) 通过变量或变量声明,方法调用或字段访问表达式引用的所有类和接口。

(注意:JLS和JVM规范允许JVM“懒散地”加载类,这会影响类加载器异常的抛出。)

有时,有人会将源代码文件放入源代码树中的错误文件夹,或者漏掉package声明。 如果您在IDE中这样做,IDE的编译器会立即告诉您这一点。 类似地,如果您使用一个像样的Java构建工具,该工具将以检测问题的方式运行javac。 但是,如果您手工构建您的Java代码,您可以这样做:编译器不会注意到问题,并且生成的“。class”文件不在您期望的位置。

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

另外,考虑从网站,文档等复制和粘贴不可见或非ASCII字符可能引起的问题。 再想想“同形异形”,就是两个字母或符号看起来一样。。。但不一样。

最后,如果您试图从(meta-inf/*.sf)中签名不正确的JAR文件启动,显然会遇到这个问题。

使用Java命令启动Java程序有三种备选语法。

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

java [ ] -jar [ ...]

例如。

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

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

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

java [ ] --module [/] [ ...]

入口点类的名称要么由本身定义,要么由可选的给定。

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

java [ ] [ ...]

其中(通常)是一个后缀为“。Java”的文件。

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

典型的Java IDE支持在IDE JVM本身或子JVM中运行Java应用程序。 由于IDE使用自己的机制来构造运行时类路径,标识主类并创建Java命令行,因此它们通常不会受到这种特殊异常的影响。

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

简而言之,如果您在IDE中遇到此问题,请检查诸如陈旧的IDE状态,损坏的项目引用或损坏的启动程序配置之类的东西。

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

来自Oracle Java教程-常见问题(及其解决方案)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有