What causes and what are the differences between NoClassDefFoundError and ClassNotFoundException?
Solution 1
The difference from the Java API Specifications is as follows.
Thrown when an application tries to load in a class through its string name using:
- The
forName
method in classClass
.- The
findSystemClass
method in classClassLoader
.- The
loadClass
method in classClassLoader
.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.
Solution 2
A ClassNotFoundException is thrown when the reported class is not found by the ClassLoader. This typically means that the class is missing from the CLASSPATH. It could also mean that the class in question is trying to be loaded from another class which was loaded in a parent classloader and hence the class from the child classloader is not visible. This is sometimes the case when working in more complex environments like an App Server (WebSphere is infamous for such classloader issues).
People often tend to confuse java.lang.NoClassDefFoundError
with java.lang.ClassNotFoundException
however there's an important distinction. For example an exception (an error really since java.lang.NoClassDefFoundError
is a subclass of java.lang.Error) like
java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory
does not mean that the ActiveMQConnectionFactory class is not in the CLASSPATH. Infact its quite the opposite. It means that the class ActiveMQConnectionFactory was found by the ClassLoader however when trying to load the class, it ran into an error reading the class definition. This typically happens when the class in question has static blocks or members which use a Class that's not found by the ClassLoader. So to find the culprit, view the source of the class in question (ActiveMQConnectionFactory in this case) and look for code using static blocks or static members. If you don't have access the the source, then simply decompile it using JAD.
On examining the code, say you find a line of code like below, make sure that the class SomeClass in in your CLASSPATH.
private static SomeClass foo = new SomeClass();
Tip : To find out which jar a class belongs to, you can use the web site jarFinder . This allows you to specify a class name using wildcards and it searches for the class in its database of jars. jarhoo allows you to do the same thing but its no longer free to use.
If you would like to locate the which jar a class belongs to in a local path, you can use a utility like jarscan ( http://www.inetfeedback.com/jarscan/ ). You just specify the class you'd like to locate and the root directory path where you'd like it to start searching for the class in jars and zip files.
Solution 3
NoClassDefFoundError
is a linkage error basically. It occurs when you try and instantiate an object (statically with "new") and it's not found when it was during compilation.
ClassNotFoundException
is more general and is a runtime exception when you try to use a class that doesn't exist. For example, you have a parameter in a function accepts an interface and someone passes in a class that implements that interface but you don't have access to the class. It also covers case of dynamic class loading, such as using loadClass()
or Class.forName()
.
Solution 4
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.
Solution 5
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.
Comments
-
krisp almost 2 years
What is the difference between
NoClassDefFoundError
andClassNotFoundException
?What causes them to be thrown? How can they be resolved?
I often encounter these throwables when modifying existing code to include new jar files. I have hit them on both the client side and the server side for a java app distributed through webstart.
Possible reasons I have come across:
- packages not included in
build.xml
for the client side of code - runtime classpath missing for the new jars we are using
- version conflicts with previous jar
When I encounter these today I take a trail-and-error approach to get things working. I need more clarity and understanding.
- packages not included in
-
user43685 about 13 yearsIt i funny that this is exactly correct answer voted the last. (Even -1 before I voted). ClassNotFoundException means the CL doesn't see .class file. NoClassDefFoundError means the .class file is there it is not loadable (possibly JNI error).
-
zardosht over 11 yearsIsn't this answer contradicting with answer form coobird?
-
Kaushik Lele over 11 yearsI tried similar example of Static block. My class Class1 has static variable "private static B foo = new B();" After compilation, I removed the B.class file from bin folder. Now from Main method of third class when I create object of Class1. The rror is thown as follws :-------- "Exception in thread "main" java.lang.NoClassDefFoundError: spring/B" ........ So it exactly mentiones which class it did not found i.e.class referred in static block and not the outer class.So it is contrary to this answer.
-
Dagang over 10 years
NoClassDefFoundError
usually occurs when there's problem (exception thrown) with the static block or static fields initialization of the class, so the class can't be initialized successfully. -
Ravi almost 9 yearsupvote. one is an
Error
and the other is anException
. :) -
user207421 almost 8 yearsUpvote for mentioning 'the name in the class file does not match the requested name'. This is a quite common cause.
-
PJTraill almost 8 yearsWhat about running the JVM with
-verbose
, or some similar option depending on the specific JVM? Probably-verbose:class
, maybe-verbose:class:jni
if using JNI, but I’m not sure about the syntax. -
PJTraill almost 8 yearsWhat about running the JVM with
-verbose
, or some similar option depending on the specific JVM? Probably-verbose:class
, maybe-verbose:class:jni
if using JNI, but I’m not sure about the syntax. If this is useful, perhaps you could show the results. -
mogsie almost 8 yearsNeither
-verbose:class
nor-verbose:jni
give any additional output relevant to the missing class. -
PJTraill almost 8 years
-verbose:class:jni
is wrong, but you can pass two separate options:-verbose:class -verbose:jni
. -
PJTraill almost 8 yearsThanks for trying it out, even if the result is disappointing. (P.S. I have since found out that
-verbose:class:jni
is wrong: one has to specify two separate options:-verbose:class -verbose:jni
.) -
batwad about 6 yearsThe last sentence * 1,000,000: 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.
-
akila almost 5 years+1 for the clarification regarding "does not mean that the ActiveMQConnectionFactory class is not in the CLASSPATH"
-
Stephen C over 4 yearsNot crystal clear. "Not updated in the classpath" is vague / imprecise. This is about the either the JAR not being present in the classpath, or the wrong version of the JAR being on the classpath. And spelling errors. And (sigh) since you posted your information as a funky graphic, we can't fix this.