El Psy Congroo

ClassNotFoundException & NoClassDefFoundError

两个异常都和找不到类有关,但引发这两个异常的原因有所不同。

  • ClassNotFoundException是在我们主动使用类名加载类时找不到对应类文件抛出的异常,这是一个Exception,需要我们显式捕获处理。参考ClassNotFoundException的JavaDoc:

    Thrown when an application tries to load in a class through its string name using:

    • The forName method in class Class.
    • The findSystemClass method in class ClassLoader .
    • The loadClass method in class ClassLoader.

    but no definition for the class with the specified name could be found.

  • NoClassDefFoundError是系统被动加载类时(例如使用new关键字),找不到对应类文件而抛出的异常,这是一个Error,继承自LinkageError,即编译期使用的类定义在运行期无法找到,或者不兼容。参考NoClassDefFoundError的JavaDoc:

    Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

    The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.

引起类找不到的主要原因如下

  • 类不在classpath中
    • 运行时指定的classpath错误
    • jar manifest文件中设置classpath错误
      • 例如maven-jar-plugin的这个bug会导致snapshot包在lib目录中和mf文件中的文件名不一致
  • 依赖冲突导致加载的类和编译的类不同
  • 类加载时,静态块或静态变量初始化失败,这种情况日志中会有ExceptionInInitializerError
  • classloader可见性问题,例如在tomcat容器中使用common loader无法加载到webapp中的类

参考:
https://javarevisited.blogspot.com/2011/06/noclassdeffounderror-exception-in.html

[[java]]