Top 5 Reasons of Exception in thread "main" java.lang.NoClassDefFoundError in Java

NoClassDefFoundError in Java
The Exception in thread "main" java.lang.NoClassDefFoundError is a common error in Java which occurs if a ClassLoader is not able to find a particular class in the classpath while trying to load it. The Exception in thread "main" suggests that this error has occurred in the main thread, the thread which is responsible for running Java application. This error can occur to any thread but if it happens in main thread then your program will crash. As per Javadoc, NoClassDefFoundError can be thrown during linking or loading of the class file. It's denoted by java.lang.NoClassDefFoundError and comes when that particular class is present during compile time but somehow not available during runtime. This could be due to missing JAR file, any permission issue, or incorrect classpath on runtime, depending upon your environment.


Java Programmers often confuse between java.lang.ClassNotFoundException and java.lang.NoClassDefFoundError in Java which is also related to class loading in Java but there is a slight difference between NoClassDefFoundError and ClassNotFoundException in Java, The ClassNotFoundException comes when Java tries to load a class by its binary name during runtime and Class is not available at that time. for example, when you load JDBC driver using Class.forName(String classname), you will get java.lang.ClassNotFoundException instead of NoClassDefFoundError.

On the other hand, NoClassDefFoundError comes when the class was available at compile time but somehow not available at runtime e.g. if static initializer block of a class throws an Exception during loading, the class will not be available for other's to use. If any class try to refer that class then the classloader will throw the java.lang.NoClassDefFoundError. If you like, you can read more about their difference in this article.




5 common causes of  Exception in thread "main" java.lang.NoClassDefFoundErro in Java

The Exception in thread "main" java.lang.NoClassDefFoundError in Java can come due to a variety of reasons in Java, But most of the time java.lang.NoClassDefFoundError comes due to CLASSPATH errors in Java. A correct understanding of how classpath works in Java is required to troubleshoot and solve the  Exception in thread "main" java.lang.NoClassDefFoundError in Java.

Anyway here are some of the common reason which has caused  Exception in thread "main" java.lang.NoClassDefFoundError in various Java application in past, your problem could well be due to any of these reasons. 

1) Missing JAR file in Classpath
The offender class is not available in the classpath of your Java application. For example, if you are getting "Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger" error in your application which means classloader of your application is not able to find org.apache.log4j.Logger class in its classpath. The simplest reasons of this error are the missing log4j.jar file in the classpath. As soon as you add that JAR into classpath the error goes away. See here to learn more about troubleshooting this particular issue.

Similarly, you might have seen java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObject which comes if you are using XMLbeans but xmlbeans-2.60.jar is not present in your classpath (see here).


Another common one is java.lang.NoClassDefFoundError: org/dom4j/DocumentException, which comes due to missing dom4j.jar file (see here).

In short, the first step to solving "Exception in thread "main" java.lang.NoClassDefFoundError" is to check if offender class is available in classpath or not. In Eclipse, you can use shortcuts like search resource (Ctrl + R) or search type (Ctrl + T) to find which JAR file that particular class belongs and then check if that JAR is available in classpath or not. See here to learn more useful Eclipse shortcuts for Java developers.


2) Due to Visibility issue between multiple Classloaders
Sometimes in complex environments e.g. Java EE container, it's possible that the offender cases is available in classpath but not visible to the classLoader which is trying to load that particular class. For example, in Java classloader work by delegation and visibility. A class loading request is first delegated to parent class loader before child class loader attempts to load it, hence any class loaded by parent class loader is visible to child class loader but the opposite is not true i.e. a class loaded by child classloader is not visible to parent class loader.

Suppose a class is used by two JAR files e.g. WAR and EJB-JAR file but it present in WAR file then it will be visible to web app classloader but not do the classloader which loads the class from EJB-JAR file.


3) Missing classpath entry in Manifest file
You can also get the "Exception in thread "main" java.lang.NoClassDefFoundError" if you are running your Java application using java -jar command and that class were not defined in manifest file's ClassPath attribute. In past, I have spent hours to figure out which JAR is missing only to find that Java is using the classpath defined in the manifest file and not the classpath environment variable.

 Exception in thread "main" java.lang.NoClassDefFoundError - Cause and solution

4) Environment Issues 
I have seen strange reasons of java.lang.NoClassDefFound error while working in Java. In one case one of the shell scripts which was starting our Java application was overriding the value of CLASSPATH environment variable. Due to this reason it's not a good idea to use the classpath environmetn variable for running Java application. Instead, you should define the classpath with list of JAR files in the start script and start your Java application using java -classpath command. See here to learn more about how to add multiople JAR files in classpath.



5) Error in Static Initializer block
One of the most common reasons for "Exception in thread "main" java.lang.NoClassDefFoundError" is error in static initializer block.  This is the block of code which is declared using static keyword and executed when a class is loaded. If suppose class A throw Exception from static initializer block and class B uses class A. In that case when class B will be loaded it will throw "Exception in thread "main" java.lang.NoClassDefFoundError" because it will not be able to find it's dependency which is class A. 

So next time, if you see the NoClassDefFound error in your Java application, make sure you search for static initializer error i.e. java.lang.ExceptionInInitializerError in your log file. That is the root cause of the NoClassDefFoundError you were seeing.


That's all on what is NoClassDefFoundError in Java and what are the common reason which causes Exception in thread "main" java.lang.NoClassDefFoundError in Java. Most of the time it's just a missing JAR file which causes this problem but sometimes it can be a nightmare to solve e.g. in case your application is picking classpath from manifest file and you are checking classpath entry somewhere else. In order to deal with java.lang.NoClassDefFoundError, two things which are most important is knowledge of Classpath and ClassLoader in Java. So, you should invest some time on it. To start with you can read Java Puzzlers by Joshua Bloch.


Reference:
https://docs.oracle.com/javase/8/docs/api/java/lang/NoClassDefFoundError.html

1 comment:

  1. What is difference between NoClassDefFoundError and a ClassNotFoundException? I guess both comes due to missing class in CLASSPATH? Why Java has two types of error for same reasons?

    ReplyDelete