如何解决 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
的包,其中包含以下类:
定义此包的文件物理存储在目录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 -> build path -> 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】:我遇到了同样的错误,我花了一整天才意识到这是一个依赖冲突问题:
我导入了两个库,A
和 B
;
A
和B
都依赖于另一个库C
,但C
的版本不同。假设A
依赖于C 1.0
和B
依赖于C 2.0
;
B
使用了只存在于 C 2.0
中的类;
然而,A
在依赖树中“更接近”,所以 Maven 使用 C 1.0
来表示 A
和 B
,甚至不会警告你(这对我来说非常令人震惊);
因此,当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 代码并添加类路径是这样的解决方案:> java -cp <JAR file> <JAVA Class file>
例如,
c:\code\prototype-app\target\classes>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
【讨论】:
【参考方案26】:我删除了一些未使用的导入,它为我解决了问题。如果你一开始就没有找到一个类,你就找不到它。
【讨论】:
删除未使用的导入不会修复ClassNotFoundException
。未使用的导入在运行时的影响为零。您一定还做了其他事情......并且解决了问题。
@StephenC 我知道我看到了什么。未使用的导入可能对运行时没有影响,但编译时间呢?
那么它们并没有被使用。他们被使用了......以错误的方式!例如,如果您导入与默认导入的某个其他类同名的类(例如当前包中或java.lang
中的类),则删除导入会更改程序,并可能修复编译时间或甚至运行时问题。但不是ClassNotFoundException
...这就是这个问题的意义所在。
(如果你知道你所看到的......复制它,并向我们展示证据。)
实际上...我想如果您有隐藏正确类的导入,并且您的编译和运行时类路径不同,它可以修复ClassNotFoundException
。但你必须犯许多不同的错误才能实现这一目标。【参考方案27】:
将所有代码放在try块中,然后在catch块中捕获异常
try
// code
catch(ClassNotFoundException e1)
e1.getmessage();
【讨论】:
这不会解决异常。这隐藏了异常。此外,"e1.getmessage()" 是 a) getMessage() 的错误大小写和 b) 不会做太多事情,因为它返回带有消息的字符串并且您没有打印或记录它或任何东西!以上是关于如何解决 ClassNotFoundException?的主要内容,如果未能解决你的问题,请参考以下文章
Faces Servlet - ClassNotFound 异常 [重复]
无法在 Tomcat 7 中初始化 FacesServlet - ClassNotFoundException
FindBugs IDEA - ClassNotFoundException com.google.wireless.android.sdk.stats.IntellijIndexingStats