如何解决 ClassNotFoundException?

Posted

技术标签:

【中文标题】如何解决 ClassNotFoundException?【英文标题】:How do I resolve ClassNotFoundException? 【发布时间】:2013-06-28 19:52:10 【问题描述】:

我正在尝试运行 Java 应用程序,但收到此错误:

java.lang.ClassNotFoundException:

冒号之后是缺少的类的位置。但是,我知道该位置不存在,因为该课程位于其他地方。如何更新该类的路径?跟类路径有关系吗?

【问题讨论】:

你必须将缺少类的jar添加到classptah中 如果您的班级有一个包,然后转到包含该班级的文件夹。例如,如果包是包 test.abc,则在测试前转到文件夹,然后执行 java -cp 。 test.abc.CLASSNAME(没有 .class)。如果没有包,则转到包含类的文件夹并说 java -cp 。类名 要么一个类没有部署到你的运行时(例如缺少 jar),要么这个类在给定的类加载器中不可见,检查这个有助于解决这些问题的工具:jhades.org 我有时也会遇到这种情况。此异常显然违反了在异常消息中说明所有必要上下文的规则。它应该提到 where 它试图寻找的东西,你的类路径上有什么。请制作更好的异常消息。不要让我们寻找可以帮助解决问题的信息。 【参考方案1】:

类路径是从中加载类的位置列表。

这些“位置”可以是目录,也可以是 jar 文件。

对于目录,JVM 将遵循预期的模式来加载类。如果我的类路径中有目录 C:/myproject/classes,并且我尝试加载类 com.mycompany.Foo,它将在类目录下查找一个名为 com 的目录,然后在该目录下一个名为 mycompany 的目录,最后它会在该目录中查找一个名为 Foo.class 的文件。

在第二种情况下,对于 jar 文件,它将在 jar 文件中搜索该类。 jar 文件实际上只是一个压缩的目录集合,如上述。如果你解压一个 jar 文件,你会得到一堆遵循上述模式的目录和类文件。

所以当JVM试图加载类定义时,它会从头到尾遍历类路径来寻找类的定义。例如,在类路径中:

C:/myproject/classes;C:/myproject/lib/stuff.jar;C:/myproject/lib/otherstuff.jar

JVM 将尝试首先查看目录 classes,然后是 stuff.jar,最后是 otherstuff.jar。 p>

当您收到 ClassNotFoundException 时,这意味着 JVM 已遍历整个类路径,但未找到您尝试引用的类。与 Java 世界一样,解决方案是检查您的类路径。

你在命令行中定义一个类路径,方法是java -cp,然后是你的类路径。在 Eclipse 等 IDE 中,您将有一个菜单选项来指定您的类路径。

【讨论】:

【参考方案2】:

您的类路径已损坏(这是 Java 世界中一个非常常见的问题)。

根据您启动应用程序的方式,您需要修改 -cp 的参数、MANIFEST.MF 中的 Class-Path 条目或磁盘布局。

【讨论】:

你能更具体一点吗?我该怎么办? 您的问题没有包含足够的信息来提供更具体的答案。考虑添加。 依赖解析/版本不匹配是基本上所有编程环境中非常常见的问题。我们可以说,任何程序所做的都是解析此类定义......问题始终是定义是什么/在哪里以及您的意思是哪个版本? 我只是强调,除了 Java 世界之外,所有软件都在努力确保找到正确版本的依赖项。我可以提到 dll-hell、包管理器、版本管理器、spring boot 材料清单和 docker 容器作为这个问题和可能的解决方案的示例。外来代码的比例越大,问题就越大。 @masterxilo 是的,但这不一定是这里的问题,你可能会叫错树。只能说类路径坏了。【参考方案3】:

这是我目前找到的best solution。

假设我们有一个名为 org.mypackage 的包,其中包含以下类:

HelloWorld(主类) 支持类 UtilClass

定义此包的文件物理存储在目录D:\myprogram(在Windows 上)或/home/user/myprogram(在Linux 上)。

文件结构如下所示:

当我们调用 Java 时,我们指定要运行的应用程序的名称:org.mypackage.HelloWorld。然而,我们还必须告诉 Java 在哪里寻找定义我们包的文件和目录。因此,要启动程序,我们必须使用以下命令:

注意:无论您当前的位置是什么,都必须执行上述java 命令。但javac 并非如此。为了 编译你甚至可以直接进入你拥有的目录 您的.java 文件并直接执行javac ClassName.java

【讨论】:

【参考方案4】:

如果您知道类的路径或包含该类的 jar,则在运行时将其添加到您的类路径中。您可以使用此处提到的类路径:

在 Windows 上

java -classpath .;yourjar.jar YourMainClass

在 UNIX/Linux 上

java -classpath .:yourjar.jar YourMainClass

【讨论】:

【参考方案5】:

如果您使用 maven,请尝试这些。我在我的项目中使用 maven,当我执行 mvn clean install 并尝试运行一个程序时,它会抛出异常。所以,我清理了项目并再次运行它,它对我有用。

我使用 Eclipse IDE。

对于运行 Junit 测试时的 Class Not Found Exception,请尝试运行一次 mvn clean test。它将编译所有的测试类。

【讨论】:

您在运行“mvn clean test”时位于哪个目录?是否与 POM 在同一目录中? 是的。从 pom 文件所在的目录运行它。【参考方案6】:

基本通用问题 - 最简单的通用答案 ;)

鉴于这些信息,我将假设您可能正在尝试使用一些简单的文本编辑器和一些命令 Shell 进行编码、构建/编译和运行简单控制台应用程序(如“Hello World”)的基本方法。

此错误发生在休闲场景中:

..\SomePath>javac HelloWorld.java
..\SomePath>java HelloWorld.class

换句话说,使用:

..\SomePath>java HelloWorld

附:添加文件扩展名 .class 会产生同样的错误。 还要确保在操作系统的环境变量的 PATH 中有 Java (JDK/JRE) bin 文件夹。(查找更多详细信息,其他帖子) P.P.S 我的假设是否正确?

【讨论】:

【参考方案7】:

如果您使用 maven,请检查您的 pom.xml 中是否有此插件:

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <!-- Attach the shade goal into the package phase -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

它会将你的依赖(异常原因)放到你的 jar 中。

仅供参考: 这将包括在最终 jar 中膨胀的所有依赖项

【讨论】:

【参考方案8】:

要通过命令行将类的位置添加到类路径中,只需在运行时添加-cp-classpath 以及类的位置。即。

java -cp "c:/location/of/file" YourProgram

或者,如果您正在运行 Eclipse 等 IDE,您可以右键单击 project -&gt; build path -&gt; configure build path 并将包含您的类的外部 JAR 添加到构建路径中,然后它应该可以正常工作。

【讨论】:

【参考方案9】:

使用';'作为分隔符。如果您的环境变量设置正确,您应该会看到您的设置。如果你的 PATH 和 CLASSPATH 是正确的,windows 应该能识别这些命令。安装 Java 时无需重新启动计算机。

【讨论】:

在windows上是(分号),在unix/linux上是':'(冒号)【参考方案10】:

将 jar 文件的完整路径添加到 CLASSPATH。 在 linux 中使用:export CLASSPATH=".:/full/path/to/file.jar:$CLASSPATH"。其他工作方式(不编辑 CLASSPATH)是在当前项目文件夹中解压缩 jar。

方法对我不起作用:

1) 使用 -cp 选项和 jar 文件的完整路径。

2) 使用-cp,当位于当前文件夹时,只有jar的名称

3) 将jar复制到当前项目文件夹

4) 将 jar 复制到 java jar 的标准位置 (/usr/share/java)

此解决方案针对 mysql-connector-java.5-*.jar 中的 com.mysql.jdbc.Driver 类报告,适用于具有 OpenJDK 版本 1.7 的 linux

【讨论】:

只有解压 JAR 对我有用,其他解决方案都没有【参考方案11】:

如果有导入语句,则上到顶部并删除,然后重新导入该类。但如果不是这种情况,请先清理然后构建。您使用的是 Netbeans 还是 Eclipse?

【讨论】:

【参考方案12】:

我也遇到了这个问题,并尝试了所有其他解决方案。我的 html 文件夹中没有 .class 文件,我只有 .java 文件。一旦我添加了 .class 文件,程序就可以正常工作了。

【讨论】:

【参考方案13】:

    如果您的类路径不正确,可能会发生这种情况

    让我们在同一个项目名下设置一个可序列化的类和可反序列化的类。您运行可序列化类,在特定文件夹中创建可序列化对象。现在您需要反序列化的数据。同时,如果您更改项目的名称,它将不起作用。您必须先运行可序列化类,然后反序列化文件。

【讨论】:

【参考方案14】:

如果你使用的是 maven 尝试 maven 更新所有项目并强制快照。 它也会清理并重建所有类路径.. 它解决了我的问题..

【讨论】:

【参考方案15】:

我刚刚做了

1.使缓存失效并重启

2.重建我的项目解决了问题

【讨论】:

【参考方案16】:

在 Java 更新后的 Windows 上可能会发生这种情况,其中旧版本的 java SDK 丢失并且存在新版本。我会检查您的 IDE 是否使用已安装的 java SDK 版本(IntelliJ:CTRL + SHIFT + ALT + S)

【讨论】:

【参考方案17】:

我尝试使用 Process 类从 C# 代码运行 .jar。 Java 代码从 Eclipse 成功运行,但它没有从 C# Visual Studio 运行,甚至直接单击 jar 文件,它总是以ClassNotFoundException: 异常停止。我的解决方案是将 java 程序导出为“可运行的 JAR 文件”而不是“JAR 文件”。希望它可以帮助某人。

【讨论】:

【参考方案18】:

如果您添加了多个 (第三方)**库和扩展 **Application

那么它可能会发生。

为此,您必须设置 multiDexEnabled true 并将扩展的 Application 类替换为 MultiDexApplication

会解决的。

【讨论】:

【参考方案19】:

我遇到了同样的错误,我花了一整天才意识到这是一个依赖冲突问题:

我导入了两个库,ABAB 都依赖于另一个库C,但C 的版本不同。假设A 依赖于C 1.0B 依赖于C 2.0B 使用了只存在于 C 2.0 中的类; 然而,A 在依赖树中“更接近”,所以 Maven 使用 C 1.0 来表示 AB,甚至不会警告你(这对我来说非常令人震惊); 因此,当B 尝试使用仅存在于C 2.0 中的类时,会抛出ClassNotFoundException

现在奇怪的是:如果您在 IDE 中导航 B 的代码并尝试跳转到仅存在于 C 2.0 中的类,它可以正常工作。 C 2.0 确实已安装并且您的 IDE 知道它,但在运行应用程序时它只是被忽略了。

这真的把我逼疯了……

我最终不得不将C 2.0 添加到我的pom.xml 中,以便可以选择它而不是C 1.0

Maven如何选择最接近的依赖请参考这篇文章:https://***.com/a/63815140/7438905

您可以使用mvn dependency:tree 来可视化依赖关系树。

【讨论】:

【参考方案20】:

在我的例子中,作为类未找到异常抛出的类具有与 ssl 证书相关的属性。关闭eclipse并以“以管理员身份运行”打开,然后问题得到解决。由于 eclipse 有问题相关的权限,它会抛出这种异常。

【讨论】:

【参考方案21】:

在将“Java 语言支持”插件从 Visual Studio Code 版本从 0.66.0 升级到 0.67.0 后,我开始遇到此问题。

降级后我可以毫无问题地运行相同的代码。

【讨论】:

【参考方案22】:

如果您已将项目移至新机器或从 git 导入,请尝试此操作。

    右键单击类>运行方式>运行配置 删除主类引用 应用 > 关闭 现在再次右键单击类 > 作为 java 应用程序运行。

它对我有用。

【讨论】:

【参考方案23】:

我在终端运行 Java 代码并添加类路径是这样的解决方案:&gt; java -cp &lt;JAR file&gt; &lt;JAVA Class file&gt; 例如, c:\code\prototype-app\target\classes&gt;java -cp ..\prototype-app-1.0-SNAPSHOT.jar com_stree.app.DetectLabels

我的运行环境: 操作系统:Windows 10 JAVA:15.0.1 Maven:3.8.1

【讨论】:

【参考方案24】:

值得注意的是,有时 Java 会谎报导致问题的类。

如果 java 尝试加载依赖于 B 类的 A 类并且无法加载 B 类,则会出现此错误。

在某些情况下,当问题为 B 时,java 报告无法加载类 A。

回忆上一次发生这种情况是在 A 类包含静态字段或加载 B 类的静态初始化程序时。

所以在检查你的类路径是否正确之后(我实际上是在启动时转储了完整的类路径)然后我对 A 类进行了二进制切割。

我的意思是,我删除了 A 中的一半代码。

如果仍然失败,我会删除另一半,依此类推,直到问题消失(希望消失)。

【讨论】:

【参考方案25】:

对不起,我迟到了,但我会用最简单的外行语言向您解释。 当您键入'javac 编译器检查程序并发现错误,首先确保您的程序与您在命令提示符下执行的目录位于同一目录中。然后它创建一个。程序的类文件。例如。如果我的程序名称是 Test.java,那么创建的类文件应该是 Test.class,它将在下一行执行。 有时 java 为您的 .class 使用其他名称,使用该名称,瞧,您将获得输出。

【讨论】:

【参考方案26】:

我删除了一些未使用的导入,它为我解决了问题。如果你一开始就没有找到一个类,你就找不到它。

【讨论】:

删除未使用的导入不会修复ClassNotFoundException。未使用的导入在运行时的影响为零。您一定还做了其他事情......并且解决了问题。 @StephenC 我知道我看到了什么。未使用的导入可能对运行时没有影响,但编译时间呢? 那么它们并没有被使用。他们被使用了......以错误的方式!例如,如果您导入与默认导入的某个其他类同名的类(例如当前包中或java.lang 中的类),则删除导入会更改程序,并可能修复编译时间或甚至运行时问题。但不是ClassNotFoundException ...这就是这个问题的意义所在。 (如果你知道你所看到的......复制它,并向我们展示证据。) 实际上...我想如果您有隐藏正确类的导入,并且您的编译和运行时类路径不同,它可以修复ClassNotFoundException。但你必须犯许多不同的错误才能实现这一目标。【参考方案27】:

将所有代码放在try块中,然后在catch块中捕获异常

try

    // code

catch(ClassNotFoundException e1)

    e1.getmessage();

【讨论】:

这不会解决异常。这隐藏了异常。此外,"e1.getmessage()" 是 a) getMessage() 的错误大小写和 b) 不会做太多事情,因为它返回带有消息的字符串并且您没有打印或记录它或任何东西!

以上是关于如何解决 ClassNotFoundException?的主要内容,如果未能解决你的问题,请参考以下文章

Java异常

Maven详解

Faces Servlet - ClassNotFound 异常 [重复]

无法在 Tomcat 7 中初始化 FacesServlet - ClassNotFoundException

在 Wildfly 的战争部署期间无法访问 jar 中的类

FindBugs IDEA - ClassNotFoundException com.google.wireless.android.sdk.stats.IntellijIndexingStats