【问题标题】:How do I resolve ClassNotFoundException?如何解决 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 它试图寻找的东西,你的类路径上有什么。请制作更好的异常消息。不要让我们寻找可以帮助解决问题的信息。

标签: java class classpath classnotfoundexception


【解决方案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】:
                  1. 如果您的类路径不正确,可能会发生这种情况

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

                  【讨论】:

                    【解决方案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】:

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

                              • 我导入了两个库,AB
                              • AB 都依赖于另一个库C,但C 的版本不同。假设A 依赖于C 1.0B 依赖于C 2.0
                              • B 使用了只存在于 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://stackoverflow.com/a/63815140/7438905

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

                              【讨论】:

                                【解决方案20】:

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

                                【讨论】:

                                  【解决方案21】:

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

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

                                  【讨论】:

                                    【解决方案22】:

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

                                    1. 右键单击类>运行方式>运行配置
                                    2. 删除主类引用
                                    3. 应用 > 关闭
                                    4. 现在再次右键单击类 > 作为 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) 不会做太多事情,因为它返回带有消息的字符串并且您没有打印或记录它或任何东西!
                                            猜你喜欢
                                            相关资源
                                            最近更新 更多