What causes and what are the differences between NoClassDefFoundError and ClassNotFoundException?

前端 未结 15 2346
忘了有多久
忘了有多久 2020-11-21 05:27

What is the difference between NoClassDefFoundError and ClassNotFoundException?

What causes them to be thrown? How can they be resolved?

相关标签:
15条回答
  • 2020-11-21 05:55

    From http://www.javaroots.com/2013/02/classnotfoundexception-vs.html:

    ClassNotFoundException : occurs when class loader could not find the required class in class path. So, basically you should check your class path and add the class in the classpath.

    NoClassDefFoundError : this is more difficult to debug and find the reason. This is thrown when at compile time the required classes are present, but at run time the classes are changed or removed or class's static initializes threw exceptions. It means the class which is getting loaded is present in classpath, but one of the classes which are required by this class are either removed or failed to load by compiler. So you should see the classes which are dependent on this class.

    Example:

    public class Test1
    {
    }
    
    
    public class Test 
    {
       public static void main(String[] args)
       {
            Test1 = new Test1();    
       }
    
    }
    

    Now after compiling both the classes, if you delete Test1.class file and run Test class, it will throw

    Exception in thread "main" java.lang.NoClassDefFoundError: Test
        at Test1.main(Test1.java:5)
    Caused by: java.lang.ClassNotFoundException: Test
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more
    

    ClassNotFoundException: thrown when an application tries to load in a class through its name, but no definition for the class with the specified name could be found.

    NoClassDefFoundError: thrown if the Java Virtual Machine tries to load in the definition of a class and no definition of the class could be found.

    0 讨论(0)
  • 2020-11-21 05:55

    Given the Class loader sussystem actions:

    http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

    This is an article that helped me a lot to understand the difference: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

    If an error occurs during class loading, then an instance of a subclass of LinkageError must be thrown at a point in the program that (directly or indirectly) uses the class or interface being loaded.

    If the Java Virtual Machine ever attempts to load a class C during verification (§5.4.1) or resolution (§5.4.3) (but not initialization (§5.5)), and the class loader that is used to initiate loading of C throws an instance of ClassNotFoundException, then the Java Virtual Machine must throw an instance of NoClassDefFoundError whose cause is the instance of ClassNotFoundException.

    So a ClassNotFoundException is a root cause of NoClassDefFoundError.
    And a NoClassDefFoundError is a special case of type loading error, that occurs at Linking step.

    0 讨论(0)
  • 2020-11-21 06:00

    ClassNotFoundException and NoClassDefFoundError occur when a particular class is not found at runtime.However, they occur at different scenarios.

    ClassNotFoundException is an exception that occurs when you try to load a class at run time using Class.forName() or loadClass() methods and mentioned classes are not found in the classpath.

        public class MainClass
        {
            public static void main(String[] args)
            {
                try
                {
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                }catch (ClassNotFoundException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
    
    
        java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at pack1.MainClass.main(MainClass.java:17)
    

    NoClassDefFoundError is an error that occurs when a particular class is present at compile time, but was missing at run time.

        class A
        {
          // some code
        }
        public class B
        {
            public static void main(String[] args)
            {
                A a = new A();
            }
        }
    

    When you compile the above program, two .class files will be generated. One is A.class and another one is B.class. If you remove the A.class file and run the B.class file, Java Runtime System will throw NoClassDefFoundError like below:

        Exception in thread "main" java.lang.NoClassDefFoundError: A
        at MainClass.main(MainClass.java:10)
        Caused by: java.lang.ClassNotFoundException: A
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    
    0 讨论(0)
  • 2020-11-21 06:01

    What is the reason for getting each of them and any thought process on how to deal with such errors?

    They're closely related. A ClassNotFoundException is thrown when Java went looking for a particular class by name and could not successfully load it. A NoClassDefFoundError is thrown when Java went looking for a class that was linked into some existing code, but couldn't find it for one reason or another (e.g., wrong classpath, wrong version of Java, wrong version of a library) and is thoroughly fatal as it indicates that something has gone Badly Wrong.

    If you've got a C background, a CNFE is like a failure to dlopen()/dlsym() and an NCDFE is a problem with the linker; in the second case, the class files concerned should never have been actually compiled in the configuration you're trying to use them.

    0 讨论(0)
  • 2020-11-21 06:04

    Example #1:

    class A{
     void met(){
       Class.forName("com.example.Class1");
     }
    }
    

    If com/example/Class1 doesn't exist in any of the classpaths, then It throws ClassNotFoundException.

    Example #2:

    Class B{
      void met(){
       com.example.Class2 c = new com.example.Class2();
     }
    }
    

    If com/example/Class2 existed while compiling B, but not found while execution, then It throws NoClassDefFoundError.

    Both are run time exceptions.

    0 讨论(0)
  • 2020-11-21 06:04

    I remind myself the following again and again when I need to refresh

    ClassNotFoundException

    Class Hierarchy

    ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable
    

    While debugging

    1. Required jar, class is missing from the classpath.
    2. Verify all the required jars are in classpath of jvm.

    NoClassDefFoundError

    Class Hierarchy

    NoClassDefFoundError extends LinkageError  extends Error extends Throwable
    

    While debugging

    1. Problem with loading a class dynamically, which was compiled properly
    2. Problem with static blocks, constructors, init() methods of dependent class and the actual error is wrapped by multiple layers [especially when you use spring, hibernate the actual exception is wrapped and you will get NoClassDefError]
    3. When you face "ClassNotFoundException" under a static block of dependent class
    4. Problem with versions of class. This happens when you have two versions v1, v2 of same class under different jar/packages, which was compiled successfully using v1 and v2 is loaded at the runtime which doesn't has the relevant methods/vars& you will see this exception. [I once resolved this issue by removing the duplicate of log4j related class under multiple jars that appeared in the classpath]
    0 讨论(0)
提交回复
热议问题