java.lang.NoClassDefFoundError is one of the most common problem while developing Java Enterprise
applications. Sometimes debugging a NoClassDefFoundError can be very
tedious as you might have to look for missing class dependencies in jar files
and may even have to decompile sometimes.
A NoClassDefFoundError is 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. In simple words, the class
was available at compile time but missing during runtime.
Purpose of this article:
To discuss how to debug multiple scenarios of NoClassDefFoundError. And find possible resolution for each scenario.
To discuss how to debug multiple scenarios of NoClassDefFoundError. And find possible resolution for each scenario.
1. NoClassDefFoundError Caused By ClassNotFoundException
1.1 Jar file(s) missing from classpath
This is the most comman case of NoClassDefFoundError.
Take a close look at the stacktrace and figure out which class is giving a ClassNotFoundException.
Now search for the jar which
contains that class. If you are using eclipse you can search using the class
name in pattern *.jar. Or you can go online and check which all jars contain
that class. For
example refer the stacktrace below:
Exception
in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:119)
at org.springframework.context.support.AbstractXmlApplicationContext.<init>(AbstractXmlApplicationContext.java:55)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:77)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:65)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:56)
at com.client.StoryReader.main(StoryReader.java:15)
Caused by:
java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
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)
at java.lang.ClassLoader.loadClassInternal(Unknown
Source)
... 6 more
The above shows that the class org.apache.commons.logging.LogFactory
is missing in classpath. When you search for it, you will find that commons-logging.jar.
Now check if this jar is present in classpath. If yes, verify the jar name and
path, if not adding it would resolve the
error.
1.2 Some dependent jar is missing which not allowing the class constructor to initialize the class object.
There might be a case where few
classes in a jar file are referring to other classes in another jar. For
example, the CallerClass in Caller.jar is shown below. It creates an instance of
ReferenceClass which is present in another jar - Reference.jar
public class CallerClass {
public static void main(String[] args) {
try
{
// Create a new instance of Class ReferenceClass
ReferenceClass referenceClass = new ReferenceClass();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
1.3 Parent and Child classloaders loading dependent jars separately
If the above two don’t work then you
are in the most complex case of NoClassDefFoundError with ClassNotFoundException.
Suppose Caller.jar is in the classpath and Reference.jar is in your Web-Archive
(ear) file and classes in Caller.jar refer to class in Reference.jar. While
loading classes in Caller.jar the system classloader attempts to use a class
found in Web archive and we get a ClassNotFoundException/NoClassDefFoundError. The
reason is that the classes in the parent classloader cannot refer directly to
classes in child classloaders. This problem is resolved by moving
the depended classes to the system classpath, e.g. moving Reference.jar to
classpath in our case. The vice-versa is not usually recommended but if the
architecture permits, moving the Caller.jar to web archive can also help.
2. NoClassDefFoundError caused by an ExceptionInInitializerError
When you see NoClassDefFoundError with
an ExceptionInInitializerError in stacktrace then a dependent class
initialization has failed. NoClassDefFoundError is just a symptom. The actual
issue is ExceptionInInitializerError which we need to find and fix. Consider the scenario explained in
1.2 above. Suppose there is a static initializer in a ReferenceClass in Reference.jar
and it failed. There would be an ExceptionInInitializerError for this class. Below,
I am manually throwing an exception to explain this:
public class ReferenceClass {
// Static initializer block executed at Class loading time
static {
// Static block code execution...
throw
new Exception("Throwing error manually");
}
}
Now if another CallerClass in Caller.jar
is using an object of ReferenceClass it would fail with a NoClassDefFoundError.
public class CallerClass {
public static void main(String[] args) {
try
{
// Create a new instance of Class ReferenceClass
ReferenceClass referenceClass = new ReferenceClass();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
It is tricky to find resolution of
such cases. You need to look at the stacktrace and find out where exactly ExceptionInInitializerError
is thrown. If it’s your code packed into the jar, you can change, recompile and
pack again. If you see this error in any class of library you are using then
you need to check what condition is causing the ExceptionInInitializerError.
3. Fixed NoClassDefFoundError but now getting NoSuchMethodError?
You are probably using a different
version of jar in your classpath then what is used during compilation. It usually
occurs when you start using a new version of a jar then what was used earlier. For example, suppose the initial
version of your Reference.jar has a ReferenceClass with method updateContact(String
address) as shown below.
public class ReferenceClass {
public void updateContact(String address){
// some logic to update
contact
}
}
Now you changed the method to updateContact(String
address, String email) and repacked it into Reference2.jar
public class ReferenceClass {
public void updateContact(String address, String email){
// some logic to update
contact & email
}
}
The CallerClass is calling the
method updateContact as below:
public class CallerClass {
public static void main(String[] args) {
try
{
// Create a new instance of Class ReferenceClass
ReferenceClass referenceClass = new ReferenceClass();
// Call updateContact
referenceClass.updateContact(“Somewhere
in World”,”gv@text.com”);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
While compiling, your code refers to
the new method but your classpath is still having Reference.jar. The system
tries to find updateContact(String, String) in Reference.jar but is unable to
find it. Hence NoSuchMethodError would be thrown. For resolution of this case, take a
close look at the stacktrace and figure out which class method is giving a NoSuchMethodError.
Now search for the jar which contains that class. If you are using eclipse you
can search using the class name in pattern *.jar. Or you can go online and
check which all jars contain that class. Now check if the correct version of
this jar is present in classpath. If not, remove the old jar from class path
and add the newer version.
Thanks for the post. Its really helpful. =)
ReplyDeleteYou are welcome
DeleteHi,
ReplyDeleteI'm facing a NoSuchMethodError in my plugin project. I got this error :
java.lang.NoSuchMethodError: org.codehaus.jackson.map.ObjectMapper.getTypeFactory()
The two jars' are : org.codehauas.jackson.mapper 1.0.6 and org.codehauas.jackson.core 1.0.6
The version are the same, but I still have the error.
Any idea ?
Thanks in advance
@Ismail : I see on stackoverflow that you were able to resolve it by adding plugin dependencies. I hope this article was helpful.
Deleteavr. 17, 2014 10:08:34 PM org.apache.catalina.core.StandardContext listenerStart
ReplyDeleteGrave: Exception lors de l'envoi de l'évènement contexte initialisé (context initialized) à l'instance de classe d'écoute (listener) org.quartz.ee.servlet.QuartzInitializerListener
java.lang.NoClassDefFoundError: javax/transaction/UserTransaction
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetPublicMethods(Unknown Source)
at java.lang.Class.getMethods(Unknown Source)
at java.beans.Introspector.getPublicDeclaredMethods(Unknown Source)
at java.beans.Introspector.getTargetMethodInfo(Unknown Source)
at java.beans.Introspector.getBeanInfo(Unknown Source)
at java.beans.Introspector.getBeanInfo(Unknown Source)
at org.quartz.impl.StdSchedulerFactory.setBeanProps(StdSchedulerFactory.java:1393)
at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:1057)
at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:1519)
at org.quartz.ee.servlet.QuartzInitializerListener.contextInitialized(QuartzInitializerListener.java:171)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4701)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5204)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5199)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.transaction.UserTransaction
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
... 19 more
Thank you. The explanation helps.
ReplyDeleteYou're welcome
DeleteThanks for a well-organized explanation. However, my case is different from any of your examples. This is a standalone client app for a JBoss EJB. It seems something like your case 2 except there's no "caused by ExceptionInInitializerError". Instead, my stack trace looks like this
ReplyDelete2017-01-16 10:31:36,551 ... Lookup of SockStatusBean failed on server URL : http-remoting://10.5.134.210:8080.java.lang.NoClassDefFoundError - Could not initialize class org.jboss.ejb.client.EJBClientContext
java.lang.NoClassDefFoundError: Could not initialize class org.jboss.ejb.client.EJBClientContext
at org.jboss.ejb.client.EJBClient.createSession(EJBClient.java:200) ~[ttjd.jar:?]
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.doCreateProxy(EjbNamingContext.java:227) ~[ttjd.jar:?]
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.createEjbProxy(EjbNamingContext.java:204) ~[ttjd.jar:?]
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.lookup(EjbNamingContext.java:187) ~[ttjd.jar:?]
at javax.naming.InitialContext.lookup(InitialContext.java:417) ~[?:1.8.0_66]
...
with no "caused by" at all. Is this the same as your case 2, do you think?
It could be either 1.2 or 2. Further stacktrace can help know the root cause.
DeleteIt turned out to be an actual error thrown in the JBoss client. One of my properties was wrong. But without JBoss logging visible I couldn't see it. Still don't understand why there was no "caused by". But thanks for your help!
DeleteWynn Hotel Casino & Spa - Mapyro
ReplyDeleteSee 3282 traveler reviews, 395 photos, & 양주 출장샵 1 tip from 안성 출장마사지 1127 visitors about Wynn Hotel Casino & Spa. "The food is good! The 제주 출장샵 rooms are nice 광주광역 출장안마 and clean and the beds are clean. " Rating: 2.5 · 3,282 reviews · Price range: $ (Based on Average 남양주 출장마사지 Nightly Rates for a Standard Room from our Partners)
Cool and that i have a swell give: How Much Is Home Renovation second story addition
ReplyDelete