Why do I get ClassNotFoundException or NoClassDefFoundError
First there is little difference between the two.
NoClassDefFoundError represents an unfound import
ClassNotFoundException represents dynamic classloading
You forgot to add the class
Use jar -tf whatever.jar to show the class is in the correct place
You forgot to add a class that this class depends upon
Use javap to look at the class (assuming you don't have the source code)
You compiled the class for the wrong version
e.g. the class is compiled for java5 but you are trying to use it on java1.4. Note that this can happen when the subclass was compiled with the correct version but its superclass was not. Often, java will report the NoClassDefFoundError on the subclass when the problem was really the fact that its superclass was compiled with the wrong version. A bytecode viewer can help with this.
The class is not visible from where it is being loaded
This happens when you have an isolated deployment (like a war) and you try to load it from outside the war. This may not be directly. e.g. A war class loads a class from outside the war which in turn tries to load a class from inside the war.
You are deploying on Windows (NTFS)
Path names in NTFS have a hard limit of 255 characters, which means that if the exploded full path is longer than 255, the path is truncated. For example this one which contains 269 characters:
/C:/JBoss/jboss-4.0.4.GA/server/Server1/tmp/deploy/tmp8590CCFF_Administration-test-blabla.ear-contents/CCFF_Administration_blabla-exp.war/WEB-INF/classes/me/you/house1/ccff/administration/controller/web/actionForms/logconfiguration/LogConfigurationListActionForm.class
This path would through an exception like this because it would truncated to something like this:
/C:/JBoss/jboss-4.0.4.GA/server/Server1/tmp/deploy/tmp8590CCFF_Administration-test-blabla.ear-contents/CCFF_Administration_blabla-exp.war/WEB-INF/classes/me/you/house1/ccff/administration/controller/web/actionForms/logconfiguration/LogConfigurationListAc
Some other error
e.g. the class has a static initialization block that is throwing an error
public class MyClass{ static{ throw new Error("Usually not reported in the NoClassDefError if this is loaded by an import :-("); } }
Not using the correct api
If you use Class.forName() this is MyClass.class.getClassLoader().loadClass(...) which will start from the classloader where your class is deployed.
You should use Thread.currentThread().getContextClassLoader().loadClass(...) to load from the current application's classloader.
Why are the error messages so uninformative?
Speak to Sun or your JDK provider
Related
Comments