What causes and what are the differences between NoClassDefFoundError and ClassNotFoundException?
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 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
aClassLoader
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.
ClassNotFoundException vs NoClassDefFoundError
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.
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.
You have to understand that the JVM
can't realize the definition of the class
you deleted can't be found, as the class
itself can't be found which automatically throw the ClassNotFoundException
.
This exception happen at runtime
so it does not matter if it compiled first or not, you deleted the file, therefore it can't be found and throw the exception
.
Note that NoClassDefFoundError
is not actually an exception, it is an Error
derived from LinkageError
while ClassNotFoundException
derive directly from java.lang.Exception
.
To resume, the NoClassDefFoundError
globally simply mean that the JVM
tried to access at runtime
something that according to the compiled
code should exists, but does not actually exist (or is not in the classpath).
Example to reproduce ClassNotFoundException
public class ClassNotFoundExceptionExample {
private static final String CLASS_TO_LOAD = "main.java.Utils";
public static void main(String[] args) {
try {
Class loadedClass = Class.forName(CLASS_TO_LOAD);
System.out.println("Class " + loadedClass + " found successfully!");
}
catch (ClassNotFoundException ex) {
System.err.println("A ClassNotFoundException was caught: " + ex.getMessage());
ex.printStackTrace();
}
}
}
Example to reproduce NoClassDefFoundError
Create a simple class Test
public class Test {
public Test() {
System.out.println("A new instance of the Test class was created!");
}
}
And a class NoClassDefFoundErrorExample
public class NoClassDefFoundErrorExample {
private static Test test = new Test();
public static void main(String[] args) {
System.out.println("The definition of Test was found!");
}
}
Now create a n executable .jar
which execute the main
method. You can specify it in the Manifest.txt
file inside the .jar
Main-Class: NoClassDefFoundErrorExample
Now run the following commands
javac Test.java
javac NoClassDefFoundErrorExample.java
jar cfm NoClassDefFoundErrorExample.jar Manifest.txt NoClassDefFoundErrorExample.class
java -jar NoClassDefFoundErrorExample.jar
Notice the NoClassDefFoundError
Exception in thread "main" java.lang.NoClassDefFoundError: TestClass
at NoClassDefFoundErrorExample.(NoClassDefFoundErrorExample.java:2)
Caused by: java.lang.ClassNotFoundException: TestClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
What is difference between ClassNotFoundException and NoClassDefFoundError?
Class not found:
http://docs.oracle.com/javase/7/docs/api/java/lang/ClassNotFoundException.html
No Class Def:
http://docs.oracle.com/javase/7/docs/api/java/lang/NoClassDefFoundError.html
"Class not found" is pretty obvious: some reflection mechanism tried to refer to it's class by it's name, but the class wasn't around, so kablooey. That's pretty obvious. The name is wrong.
The sneaky one is the "No Class Def Found" error. That happens when you compile the code & everything is hunky-dorey, but at runtime, that class that was available at compile time just isn't there. Or, even more sneaky, it's there, but at the wrong version so it can't be used.
The first issue points to a configuration error. You've just got the wrong name.
The second issue points to a build error. You've either lost something from the build path, or you're running in a different JVM, or something whacky like that.
"Class Not Found" is usually pretty easy to fix, but "No Class Def" can have you pulling your hair out. If you're experiencing the latter, set about proving that the class mentioned is on the classpath, or in a jar on the classpath. Usually that effort shakes the problem out when I see it.
What is Difference between ClassNotFoundException vs NoClassDefFoundError vs Could not find or load main class XYZ?
NoClassDefFoundError
- is a run-time error, thrown when the Definition of the class (which is .class
file) cannot be found at run-time.
- Imagine you've compiled class
A.java
alongside other files of your project; however, later on, you've removed compiledA.class
file. So, compilation went fine, but actual bytecode of the class definition is absent, asA.class
has been removed.
ClassNotFoundException
- is a checked exception, thrown when your application tries to load the class through its String name, but the class isn't available on class-path.
- An example can be
Class.forName("com.mysql.jdbc.driver");
method call in your code, when, however, you don't havecom.mysql.jdbc.driver
available in your project.
Couldn't find or load main class XYZ
- is an error, indicating, that the class you instruct JVM to run, doesn't contain the must have entry-point public static void main(String[] args)
method, and reasons for this can be different, mainly one from this list:
- you don't provide a correct Fully Qualified Name of your main class;
- main method is not defined with the correct signature;
- you messed up the packaging / you don't run the program with
super.sub.grandchild.MainClass
name; - you have
.class
postfix after your classname, which you should remove.
Why am I getting a NoClassDefFoundError in Java?
This is caused when there is a class file that your code depends on and it is present at compile time but not found at runtime. Look for differences in your build time and runtime classpaths.
How can I solve java.lang.NoClassDefFoundError?
After you compile your code, you end up with .class
files for each class in your program. These binary files are the bytecode that Java interprets to execute your program. The NoClassDefFoundError
indicates that the classloader (in this case java.net.URLClassLoader
), which is responsible for dynamically loading classes, cannot find the .class
file for the class that you're trying to use.
Your code wouldn't compile if the required classes weren't present (unless classes are loaded with reflection), so usually this exception means that your classpath doesn't include the required classes. Remember that the classloader (specifically java.net.URLClassLoader
) will look for classes in package a.b.c in folder a/b/c/ in each entry in your classpath. NoClassDefFoundError
can also indicate that you're missing a transitive dependency of a .jar file that you've compiled against and you're trying to use.
For example, if you had a class com.example.Foo
, after compiling you would have a class file Foo.class
. Say for example your working directory is .../project/
. That class file must be placed in .../project/com/example
, and you would set your classpath to .../project/
.
Side note: I would recommend taking advantage of the amazing tooling that exists for Java and JVM languages. Modern IDEs like Eclipse and IntelliJ IDEA and build management tools like Maven or Gradle will help you not have to worry about classpaths (as much) and focus on the code! That said, this link explains how to set the classpath when you execute on the command line.
Capitalization and NoClassDefFoundError vs ClassNotFoundException
HFS+ (Mac Extended) is usually not case sensitive. Since Mac OS 10.3 Apple introduced HFSX which can be case sensitive (but is not the default). If you did not specify the option by the disk initialization then your volume is most likely case insensitive.
See: http://en.wikipedia.org/wiki/HFS_Plus
Related Topics
How to Stop Java Process Gracefully
Classpath Does Not Work Under Linux
Inner Class Can Access But Not Update Values - Asynctask
Org.Apache.Http.Entity.Fileentity Is Deprecated in Android 6 (Marshmallow)
Custom Listview Adapter Getview Method Being Called Multiple Times, and in No Coherent Order
Get Nested Json Object With Gson Using Retrofit
How to Display Data from Firestore in a Recyclerview With Android
Android on Text Change Listener
Check Orientation on Android Phone
How to Create Interface Between Fragment and Adapter
Noclassdeffounderror - Eclipse and Android
How to Make a .Jar Out from an Android Studio Project
How to Set Httpresponse Timeout For Android in Java
Hadoop "Unable to Load Native-Hadoop Library For Your Platform" Warning
Decompiling Dex into Java Sourcecode