当前位置: 首页 > 知识库问答 >
问题:

ClassLoader.loadClass()意外地抛出NoClassDefFoundError而不是ClassNotFoundExcure

薛英卫
2023-03-14

我有一个类命名为MyClass,所以当我调用classloader.load类("myclass")抛出一个NoClassDefFoundError而不是ClassNotFoundExc0019

注意-我已将大写字母改为小写字母

当我使用完全不同的字符串ABC我得到ClassNotFoundExc0019作为预期。

请在下面找到代码片段。

    public class Test {

    public static void main(String[] args) {
        // normal conditions
        try {
            Test.class.getClassLoader().loadClass("MyClass");
            System.out.println(" Successfully loaded an existing class ");
        } catch (ClassNotFoundException notExpected) {

        }

        // expected
        try {
            Test.class.getClassLoader().loadClass("ABC");
        } catch (ClassNotFoundException expected) {
            System.out.println("Expected");
        }

        try {
            Test.class.getClassLoader().loadClass("myclass");
        } catch (ClassNotFoundException expected) {
            System.out.println("Expected but not coming");
        }
    }
}

//

// sample class used for the above in separate file
// 
public class MyClass
{ 

}

输出:

Successfully loaded an existing class 
Expected
Exception in thread "main" java.lang.NoClassDefFoundError: myclass (wrong name: MyClass)

[![Java8机器上的输出][1][1]

这是不重复的,因为我正在寻找不同的例外情况下的名称更改方案,请再次检查

共有2个答案

万修然
2023-03-14

我已经复制了你的程序,并在我的机器上运行(Javajdk1.8。0_121Windows 10)。它产生的产出是:

Expected
Expected but not coming

因此,您可能有一些以前的测试部分尚未删除,或者您运行的jvm有一个bug,该bug已在较新版本中修复(不太可能,但可能性仍然存在)。

有一篇关于这些例外情况的非常好的文章:可在此处找到

所以NoClassDefFoundError(顺便说一句,这是一个错误,而不仅仅是一个例外!)当类在编译时可用时抛出,但稍后已在运行时从类路径中删除。JVM确实依赖于这个类,但它并不存在,所以JVM被迫抛出这样的错误。

您能重新编译您的项目,并确保在编译过程中磁盘上没有真正的“myclass.java”文件吗?

我要检查的另一个选项是将JVM升级到最新版本并重试。

顾乐池
2023-03-14

ClassLoader使用的ClassNotFoundExc0019在进行loadClass尝试时立即报告不存在的类,与当类有以下情况时抛出的LinkageError的子类型之间有根本的区别已找到,但违反了结构约束或无法解决依赖关系。

由于延迟解析/验证,这些LinkageError(其中包括NoClassDefFoundError)的子类型甚至可能在很晚的时候抛出。

所以在你的例子中,一个类文件已经被加载,显然是因为你的操作系统或文件系统不区分大小写,但是由于名称不匹配,NoClassDefFoundError被抛出在定义类中(注意,这个方法需要预期的名称作为参数)。

正如这个答案中所解释的,如果您将类文件存储到jar文件中,而不是依赖于文件系统,那么您将获得一个独立于系统的一致行为。

 类似资料:
  • 我在服务层的spring-boot应用程序中使用了Hystrix(Camden.sr7版本),而没有回退方法。Service的方法之一如下所示: 对于这样的响应,不清楚实际上是从哪个方法抛出异常的。如果我将版本更改为brixton.sr5(以前的版本),它将返回清晰的响应: 因此Hystrix的新版本(实际上是spring-cloud-dependencies的新版本)不会抛出HystrixRun

  • 既然我们可以在Javascript中使用关键字抛出任何东西,那么我们就不能直接抛出一个错误消息字符串吗? 有人知道这里面有什么陷阱吗? 让我对此添加一些背景:在JavaScript世界中,人们通常依赖参数检查而不是使用try-catch机制,因此只使用抛出致命错误是有意义的。不过,为了能够捕捉一些系统错误,我必须为我自己的错误使用一个不同的类,而不是创建错误的子类,我认为我应该只使用String。

  • 问题内容: 我有一个需要使用Jackson从JSON反序列化的类。类结构如下所示: 反序列化对象通常效果很好;除了,它与错误代码互操作,当列表为空时,错误代码发出错误的值。也就是说,不是发出: 它发出: 杰克逊遇到以下情况时会抛出此异常: 当然,所有这些都是有道理的。输入错误。 但是,这种情况下的空列表与任何代码都不相关;如果是的话,null我不在乎。null如果无法反序列化该属性,是否有任何方法

  • 问题内容: 考虑以下代码: 无需添加方法签名即可编译该代码。(它与同样表现到位,太)。 我理解为什么 可以 安全地运行它,因为实际上不能将其引发在块中,因此不能引发已检查的异常。我有兴趣知道在何处指定此行为。 并非永远都不会达到目标:以下代码也会编译: 但是,如果抛出一个检查的异常,它不会像我期望的那样编译: 在JLS Sec 11.2.2中 ,它说: 一,其抛出的表达式语句(§14.18)具有静

  • 问题内容: 使用Spring Security 4.0.2.RELEASE 对于使用spring-security框架的基本用户身份验证,我实现了spring-security 当用户尝试使用正确的用户名登录时, 错误的 密码和用户的 帐户已经被锁定 ,那么我希望spring- security身份验证模块会抛出异常,但是会抛出异常 我的问题是 为什么spring-security正在处理用户进行

  • 使用Spring Security 4.0.2。发布 对于使用Spring Security框架的基本用户身份验证,我实现了Spring Security性DaoAuthenticationProvider 当用户尝试使用正确的用户名登录时,错误的密码和用户的帐户已被锁定,那么我预计Spring Security身份验证模块将引发BadCredentialsException,但它会引发Locke