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

前端 未结 15 2348
忘了有多久
忘了有多久 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 06:08

    The difference from the Java API Specifications is as follows.

    For ClassNotFoundException:

    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.

    For NoClassDefFoundError:

    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.

    So, it appears that the NoClassDefFoundError occurs when the source was successfully compiled, but at runtime, the required class files were not found. This may be something that can happen in the distribution or production of JAR files, where not all the required class files were included.

    As for ClassNotFoundException, it appears that it may stem from trying to make reflective calls to classes at runtime, but the classes the program is trying to call is does not exist.

    The difference between the two is that one is an Error and the other is an Exception. With NoClassDefFoundError is an Error and it arises from the Java Virtual Machine having problems finding a class it expected to find. A program that was expected to work at compile-time can't run because of class files not being found, or is not the same as was produced or encountered at compile-time. This is a pretty critical error, as the program cannot be initiated by the JVM.

    On the other hand, the ClassNotFoundException is an Exception, so it is somewhat expected, and is something that is recoverable. Using reflection is can be error-prone (as there is some expectations that things may not go as expected. There is no compile-time check to see that all the required classes exist, so any problems with finding the desired classes will appear at runtime.

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

    ClassNotFoundException is thrown when there is attempt to load the class by referencing it via a String. For example the parameter to in Class.forName() is a String, and this raises the potential of invalid binary names being passed to the classloader.

    The ClassNotFoundException is thrown when a potentially invalid binary name is encountered; for instance, if the class name has the '/' character, you are bound to get a ClassNotFoundException. It is also thrown when the directly referenced class is not available on the classpath.

    On the other hand, NoClassDefFoundError is thrown

    • when the actual physical representation of the class - the .class file is unavailable,
    • or the class been loaded already in a different classloader (usually a parent classloader would have loaded the class and hence the class cannot be loaded again),
    • or if an incompatible class definition has been found - the name in the class file does not match the requested name,
    • or (most importantly) if a dependent class cannot be located and loaded. In this case, the directly referenced class might have been located and loaded, but the dependent class is not available or cannot be loaded. This is a scenario where the directly referenced class can be loaded via a Class.forName or equivalent methods. This indicates a failure in linkage.

    In short, a NoClassDefFoundError is usually thrown on new() statements or method invocations that load a previously absent class (as opposed to the string-based loading of classes for ClassNotFoundException), when the classloader is unable to find or load the class definition(s).

    Eventually, it is upto the ClassLoader implementation to throw an instance of ClassNotFoundException when it is unable to load a class. Most custom classloader implementations perform this since they extend the URLClassLoader. Usually classloaders do not explicitly throw a NoClassDefFoundError on any of the method implementations - this exception is usually thrown from the JVM in the HotSpot compiler, and not by the classloader itself.

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

    With the names itself we can easily identify one from Exception and other one is from Error.

    Exception: Exceptions occurs during the execution of program. A programmer can handle these exception by try catch block. We have two types of exceptions. Checked exception which throws at compile time. Runtime Exceptions which are thrown at run time, these exception usually happen because of bad programming.

    Error: These are not exceptions at all, it is beyond the scope of programmer. These errors are usually thrown by JVM.


    image source

    Difference:

    ClassNotFoundException:

    • Class loader fails to verify a class byte code we mention in Link phase of class loading subsystem we get ClassNotFoundException.
    • ClassNotFoundException is a checked Exception derived directly from java.lang.Exception class and you need to provide explicit handling for it
    • ClassNotFoundException comes up when there is an explicit loading of class is involved by providing name of class at runtime using ClassLoader.loadClass(), Class.forName() and ClassLoader.findSystemClass().

    NoClassDefFoundError:

    • Class loader fails to resolving references of a class in Link phase of class loading subsystem we get NoClassDefFoundError.
    • NoClassDefFoundError is an Error derived from LinkageError class, which is used to indicate error cases, where a class has a dependency on some other class and that class has incompatibly changed after the compilation.
    • NoClassDefFoundError is a result of implicit loading of class because of a method call from that class or any variable access.

    Similarities:

    • Both NoClassDefFoundError and ClassNotFoundException are related to unavailability of a class at run-time.
    • Both ClassNotFoundException and NoClassDefFoundError are related to Java classpath.
    0 讨论(0)
  • 2020-11-21 06:12

    Difference Between ClassNotFoundException Vs NoClassDefFoundError

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

    A NoClassDefFoundError (NCDFE) happens when your code runs "new Y()" and it can't find the Y class.

    It may simply be that Y is missing from your class loader like the other comments suggest, but it could be that the Y class isn't signed or has an invalid signature, or that Y is loaded by a different classloader not visible to your code, or even that Y depends on Z which couldn't be loaded for any of the above reasons.

    If this happens, then the JVM will remember the result of loading X (NCDFE) and it will simply throw a new NCDFE every time you ask for Y without telling you why:

    class a {
      static class b {}
      public static void main(String args[]) {
        System.out.println("First attempt new b():");
        try {new b(); } catch(Throwable t) {t.printStackTrace();}
        System.out.println("\nSecond attempt new b():");
        try {new b(); } catch(Throwable t) {t.printStackTrace();}
      }
    }
    

    save this as a.java somewhere

    The code simply tries to instantiate a new "b" class twice, other than that, it doesn't have any bugs, and it doesn't do anything.

    Compile the code with javac a.java, Then run a by invoking java -cp . a -- it should just print out two lines of text, and it should run fine without errors.

    Then delete the "a$b.class" file (or fill it with garbage, or copy a.class over it) to simulate the missing or corrupted class. Here's what happens:

    First attempt new b():
    java.lang.NoClassDefFoundError: a$b
        at a.main(a.java:5)
    Caused by: java.lang.ClassNotFoundException: a$b
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        ... 1 more
    
    Second attempt new b():
    java.lang.NoClassDefFoundError: a$b
        at a.main(a.java:7)
    

    The first invocation results in a ClassNotFoundException (thrown by the class loader when it can't find the class), which must be wrapped in an unchecked NoClassDefFoundError, since the code in question (new b()) should just work.

    The second attempt will of course fail too, but as you can see the wrapped exception is no more, because the ClassLoader seems to remember failed class loaders. You see only the NCDFE with absolutely no clue as to what really happened.

    So if you ever see a NCDFE with no root cause, you need to see if you can track back to the very first time the class was loaded to find the cause of the error.

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

    ClassNotFoundException is a checked exception that occurs when we tell JVM to load a class by its string name using Class.forName() or ClassLoader.findSystemClass() or ClassLoader.loadClass() methods and mentioned class is not found in the classpath.

    Most of the time, this exception occurs when you try to run an application without updating the classpath with required JAR files. For Example, You may have seen this exception when doing the JDBC code to connect to your database i.e.MySQL but your classpath does not have JAR for it.

    NoClassDefFoundError error occurs when JVM tries to load a particular class that is the part of your code execution (as part of a normal method call or as part of creating an instance using the new keyword) and that class is not present in your classpath but was present at compile time because in order to execute your program you need to compile it and if you are trying use a class which is not present compiler will raise compilation error.

    Below is the brief description

    You can read Everything About ClassNotFoundException Vs NoClassDefFoundError for more details.

    0 讨论(0)
提交回复
热议问题