ClassNotFoundException versus NoClassDefFoundError

ClassNotFoundException and NoClassDefFoundError are normally raised when the JVM is unable to find a specific class.

These exceptions, are commonly seen in Java applications, however sometimes they are not well understood by Java developers. Although these exceptions have some similarity, they also have some subtle differences.

In this tutorial we will look at some of the differences between both types of exceptions.

ClassNotFoundException

ClassNotFoundException is probably the most common Java exception related to loading classes. The most common scenario for this type of exception is when the JVM is requested to load a particular class by its fully qualified name. To achieve this it delegates to the class loader, if the class loader cannot find this class the Exception is raised.

Some common scenarios when this exception is raised include:

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

For example the below code attempts to locate a class that does not exist, which results in a ClassNotFoundException:

1
2
3
4
5
@Test(expected = ClassNotFoundException.class)
public void classNotFound_throwsClassNotFoundException()
        throws ClassNotFoundException {
    Class.forName("com.stephenenright.DoesNotExist");
}

By throwing this exception the class loader informs the client that the class definition could not be found and loaded.

ClassNotFoundException Resolution

This exception is normally easy to resolve. Firstly you should check the appropriate classpath to ensure the class or jar file is correctly listed. If it is not, move the class to a location listed on the classpath, or add the missing location to the classpath.

You could also use the below method to aid with resolution:

1
URLClassLoader.getUrls()

The following command may also help

1
find *.jar -exec jar -tf '{}'\; | grep MissingClass

NoClassDefFoundError

NoClassDefFoundError is another exception that is raised by the class loader in response to loading a class. This exception is commonly thrown in the following scenarios:

  • Thrown when creating a new class if the definition cannot be found.
  • Thrown when calling a method on a class.

This error is different to ClassNotFoundException because it is thrown after the JVM could successfully compile the class, but it could not be located at runtime.

Let’s simulate this exception within code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test(expected = NoClassDefFoundError.class)
public void initError_throwsNoClassDefFoundError() {
    TaskNoClassDefFoundError cls = new TaskNoClassDefFoundError();
    cls.createTask();
}

public static class TaskNoClassDefFoundError {
    public InitErrorTask createTask() {
        InitErrorTask errorTask;
        try {
            errorTask = new InitErrorTask();
        } catch(Throwable t) {
            //do nothing
        }
        errorTask = new InitErrorTask();
        return errorTask;
    }
}

private static class InitErrorTask {
    static int value = 1000 / 0;
}

The above code simulates the error by throwing an exception when the InitErrorTask is initialized due to the error initializing the static variable.

Another approach to simulating this error is two create two classes:

1
2
3
4
5
public class X {
}

public class Y extends X {
}
1
2
3
4
5
public class NoClassDefFoundErrorExample {
    public static void main(String[] args) {
        Y y = new Y();
    }
}

After the above code is compiled remove the class X.

NoClassDefFoundError Resolution

To resolve this error the missing class must exist on the classpath of the appropriate class loader.

We also need to ensure that the class is not loaded from different context class loaders. If this is the case the class may exist in different class loaders. For information on classloaders see.

We can use the same methods mentioned previously to help with debugging:

1
2
find *.jar -exec jar -tf '{}'\; | grep MissingClass
URLClassLoader.getUrls()

Conclusion

In this tutorial we looked at the difference between a ClassNotFoundException and NoClassDefError in Java.