Saturday, July 31, 2021

Difference between ClassNotFoundException vs NoClassDefFoundError in Java

ClassNotFoundException vs NoClassDefFoundError
Though both of these errors are related to missing classes in the classpath, the main difference between them is their root cause. ClassNotFoundExcpetion comes when you try to load a class at runtime by using Class.forName() or loadClass() and requested class is not present in the classpath for example when you try to load MySQL or Oracle driver class and their JAR is not available, while in case of NoClassDefFoundError requested class was present at compile time but not available at runtime. Sometimes due to an exception during class initialization e.g. exception from static block causes NoClassDefFoundError when a failed-to-load class was later referenced by the runtime. 

In last few weeks I have been facing a cluster of ClassNotFoundException and NoClassDefFoundError while setting up a new project in Java. This new Java project has lots of dependency on various jars and some of the jars even contains the same name of the file which makes my problem even more problematic. 

While working with NoClassDefFoundError and ClassNotFoundException I thought to document my experience and I have already shared some on 3 ways to resolve NoClassDefFoundError in Java and how to resolve ClassNotFoundException in Java. in this article though the focus will be on similarities and differences between java.lang.ClassNotFoundException and java.lang.NoClassDefFoundError in Java.




NoClassDefFoundError vs ClassNotFoundException

Before seeing the differences between ClassNotFoundException and NoClassDefFoundError let's see some similarities which are main reason of confusion between these two errors:

1) Both NoClassDefFoundError and ClassNotFoundException are related to unavailability of a class at run-time.

2) Both ClassNotFoundException and NoClassDefFoundError are related to Java classpath.


Now let's see the difference between NoClassDefFoundError and ClassNotFoundException :

Difference between ClassNotFoundException and NoClassDefFoundError in Java

1. Root Cause

ClassNotFoundException comes in java if we try to load a class at run-time using with Class.forName() or ClassLoader.loadClass() or ClassLoader.findSystemClass() method and requested class is not available in Java.

The most of the time it looks like that we have the class in classpath but eventually it turns out to be an issue related to classpath and application may not be using classpath what we think it was using like classpath defined in jar's manifest file will take precedence over CLASSPATH or -cp option, for more details see How Classpath works in Java.

On the other hand NoClassDefFoundError is little different than ClassNotFoundException, in this case culprit class was present during compile time and let's application to compile successfully and linked successfully but not available during run-time due to various reason.

2)  Exception vs Error

ClassNotFoundException is a checked Exception derived directly from java.lang.Exception class and you need to provide explicit handling for it while NoClassDefFoundError is an Error derived from LinkageError.

3) ClassLoaders

If you are using ClassLoader in Java and have two class loaders then if a ClassLoader tries to access a class that is loaded by another classloader will result in ClassNoFoundException.

4) Explicit vs Implicit Class Loading

The ClassNotFoundException comes up when there is an explicit loading of the class is involved by providing the name of the class at runtime using ClassLoader.loadClass(), Class.forName(),  while NoClassDefFoundError is a result of implicit loading of class because of a method call from that class or any variable access.

Please let us know if you are aware of any other difference between NoClassDefFoundError and ClassNotFoundException in Java, I would be happy to incorporate those.


Related post :
How to resolve NoClassDefFoundError in Java
How HashMap works in Java?
How Garbage Collection works in Java?
Why String is immutable in Java?
10 practical tips on Java debugging with eclipse
How Synchronization works in Java?
How Classpath works in Java?

13 comments :

chiths said...

I am encountering a weird situation.
Class.forName("org.xyz.ValidationMessage") works

However in a method in class DataValidationException
public ValidationMessage .getValidationMsg()
{
return new ValidationMessage (...);
//args match
}

I get the error java.lang.NoClassDefFoundError:org.xyz.ValidationMessage

How is this possible, Class.forName for both DataValidationMessage and ValidationMessage works, clearly they are recognized by the classloader So what could be the issue.

The application is hosted in tomcat 6.x and is running on jdk 1.6 build17

Any help would be deeply appreciated...

regds,
Chiths

Javin @ FIX Protocol Tutorial said...

hi Anonymous, I will write when I have a good topic to wrote about electronic trading system, currently I have written about FIX Protocol and you can check that.

helios said...

Good differences. I agree that both NoclassDefFoundError and ClassNotFoundException shares some natural similarity which doesn't exist and create confusion on java programmer's mind.

Anonymous said...

I just encountered a use case in which one delegates the other - Using custom ant task to compile my own code. very confusing.... in short: java.lang.NoClassDefFoundError: somePackage/someClass at java.lang.Class.forName0(Native Method)
...
Caused by: java.lang.ClassNotFoundException: somePackage/someClass

Anonymous said...

A NoClassDefFoundException is
thrown if a class is referenced with
Java’s “new” operator (i.e. static loading)
but the runtime system cannot find the
referenced class.

class MyClass {
public static void main(String args[]) {
Car c = new Car();
}
}

------------------------------
Class.forName (String className); //static method which returns a Class


A ClassNotFoundException is thrown when an application tries to load in a
class through its string name using the following methods but no definition for the
class with the specified name could be found:
􀂃 The forName(..) method in class - Class.
􀂃 The findSystemClass(..) method in class - ClassLoader.
􀂃 The loadClass(..) method in class - ClassLoader.

rahul said...

ClassNotFoundException means compiler not able to find specified .class file.
NoClassDefFoundError means compile not able to load .class file.
Both can happen because of wrong classpath set.

Unknown said...

Thanks for providing such useful information...its working.

Parvez said...

Isn't this statement "Both ClassNotFoundException and NoClassDefFoundError are related to java classpath." wrong? For e.g. if you try Class.forName by passing wrong name you get ClassNotFoundException and that nothing to do with classpath.

Anonymous said...

@Parvez - puting a wrong classname is just similar to not having that class on the classpath

Unknown said...

Your 3rd point is not much clear to me, So I tried one example with one of the custom class loader mention below :

CustomClassLoader cl=new CustomClassLoader(Test.class.getClassLoader());
Class test1=cl.loadClass("Palindrome");
System.out.println(test1.getClassLoader());

Class test2=Class.forName("Palindrome");
System.out.println(test2.getClassLoader());

It didnt throw any error or exception.

Unknown said...

How to set classpath plz tell me

javin paul said...

Hello @Unknown, it's just like setting another environment variable, but if you need guidance, I have blogged about it earlier on how to set classpath in Java you can check that article.

Unknown said...

howto resolve NoClassDefFoundError.

Post a Comment