|
Problem(Abstract) |
This is a problem determination document to help with
resolving Classloader problems for all releases and editions of v5.0,
v5.1, and v6.0 of the IBM WebSphere® Application Server product. |
|
|
|
Resolving the
problem |
 |
This document assumes you have already gone through the TroubleShooting
document for Classloader problems, as well as gathered the MustGather
information to debug Classloader problems. If you have not, review those
two documents before proceeding.
The following are some examples of common Classloader problems and some
basic information on how to resolve them:
- java.lang.ClassNotFoundException - This exception
is thrown when the JVM tries to load in a class, but no definition for the
class with the specified name could be found. When debugging
ClassNotFoundExceptions, it is generally not very helpful to gather
classloader traces. Rather, we need to look at which class cannot be found
and make sure that the class is visible on the logical classpath of the
context classloader, or the classloader which was invoked to load the
class.
The following is an example of a ClassNotFoundException you might see:
java.lang.ClassNotFoundException:
com.ibm.faces.webapp.JSResourceServlet |
|
For an exception such as this one, we
need to first determine where is the JSResourceServlet.class
located. Is the class in an application utility JAR, a shared library JAR
or path, an embedded RAR, a WebSphere JAR, an EJB JAR, a WAR class or lib
JAR, a resource driver JAR, etc...?
Then we need to make sure that this location is visible on the classpath
of the classloader expected to load the class. The Application Server
classloader and JVM verbose classloader traces will assist determining
whether these JARs or paths exist on the classpaths of the application,
JVM or Application Server ExtClassLoaders, and whether any other classes
were loaded from these JARs or paths.
You should also open the jar that contains this class and ensure that the
class is there, and that this jar has no permission issues, such as read
only access for the root user. |
|
- java.lang.NoClassDefFoundError - This exception is
thrown if the JVM or a ClassLoader instance tries to load in the
definition of a class 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. These issues can
be harder to debug and Classloader, bootstrap, and JVM verbose traces are
recommended for debugging.
- java.lang.ClassCastException - This exception is
generally thrown under the following circumstances:
- We try to cast an object to a subclass of which it is not an instance.
- We try to cast a class where the cast target class was loaded by a
different classloader than that which loaded the cast source class.
To debug ClassCastExceptions, it is helpful to have the Classloader,
bootstrap, and JVM verbose traces.
Note: Loading two versions of a class involved in a cast statement
is not necessarily the cause of a cast exception. It's just a necessary
condition when determining cast exceptions of the second type, above. You
should determine if the cast is invalid before determining whether the
cast appears valid, but fails due to condition 2 above.
The following is an example of a ClassCastException you might see: |
|
java.lang.ClassCastException
at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
at
com.ibm.ws.webcontainer.srt.TldListenerParser.<init>(TldListenerParser.java:45)
at
com.ibm.ws.webcontainer.srt.TldListenerProcessor.<init>(TldListenerProcessor.java:30)
at
com.ibm.ws.webcontainer.srt.WebGroup.loadLifecycleListeners(WebGroup.java:1645)
at com.ibm.ws.webcontainer.srt.WebGroup.loadWebApp(WebGroup.java:405)
at com.ibm.ws.webcontainer.srt.WebGroup.init(WebGroup.java:212)
at
com.ibm.ws.webcontainer.WebContainer.addWebApplication(WebContainer.java:1047) |
|
The class causing the cast exception is usually indicated
in the exception. We then determine the cast statement that is executing,
if possible. They have the form:
(Target_Class)Source_Object) |
If the cast exception is due to the target class not being an instance of
the source object (class), then the problem should be debugged by whomever
owns the cast statement. This could be the application, Application
Server, or a 3rd party tool.
If the cast exception is due to the target class being loaded by a
different classloader than that which loaded the source object (Class),
then we have to determine whether the class should be made visible on the
classloader which loaded the source object class. It must be that this
class is overriding one provided by Application Server or on the JVM
classpath. This is typically an application classloader or a server-scoped
shared library (an EAR, WAR, or user-defined classloader)
Here is an example classloader trace. Note that the text in blue are
comments that do not appear in the traces, but have been included here for
a clearer picture of what the traces are telling us:
<-- Comments here |
|
<-- Begin loading the
org.apache.xerces.jaxp.SAXParserImpl class
5b55a9 CompoundClass > loadClass
name=org.apache.xerces.jaxp.SAXParserImpl this=com.ibm.ws.classloader.CompoundClassLoader@1c0e6e
<-- Begin search for the
org.apache.xerces.jaxp.SAXParserImpl class
5b55a9 CompoundClass > findClass
name=org.apache.xerces.jaxp.SAXParserImpl
this=com.ibm.ws.classloader.CompoundClassLoader@1c0e6e
5b55a9 CompoundClass d class
org.apache.xerces.jaxp.SAXParserImpl found in
SinglePathClassProvider :
com.ibm.ws.classloader.SinglePathClassProvider@1f9f538 classpath =
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xercesImpl.jar
<-- End search for
org.apache.xerces.jaxp.SAXParserImpl class since we found it in
xercesImpl.jar
5b55a9 CompoundClass < findClass
5b55a9 CompoundClass d loaded
org.apache.xerces.jaxp.SAXParserImpl from
this=com.ibm.ws.classloader.CompoundClassLoader@1c0e6e
Local ClassPath:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/classes:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/mail.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/log4j.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xalan.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xercesImpl.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war:
5b55a9 CompoundClass d loaded
org.apache.xerces.jaxp.SAXParserImpl from
this=com.ibm.ws.classloader.CompoundClassLoader@1c0e6e
<-- Loaded the
org.apache.xerces.jaxp.SAXParserImpl class using Classloader
"CompoundClassLoader@1c0e6e"
Local ClassPath:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/classes:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/mail.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/log4j.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xalan.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xercesImpl.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war:
<-- The classpath in which the Classloader is
searching, we can see this is a WAR Classlaoder
Delegation Mode: PARENT_LAST
5b55a9 CompoundClass
d loaded
org.apache.xerces.jaxp.SAXParserImpl using classloader=
com.ibm.ws.classloader.CompoundClassLoader@1c0e6e
Local ClassPath:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/classes:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/mail.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/log4j.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xalan.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war/WEB-INF/lib/xercesImpl.jar:
/opt/WebSphere/AppServer/installedApps/was51Cell/MyApp.ear/MyWar.war:
Delegation Mode: PARENT_LAST
5b55a9 CompoundClass < loadClass
<-- Finished loading the
org.apache.xerces.jaxp.SAXParserImpl class
5b55a9 SystemErr
R java.lang.ClassCastException
5b55a9 SystemErr R at
javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
5b55a9 SystemErr R at
javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
5b55a9 SystemErr R at
com.ibm.ws.webcontainer.srt.TldListenerParser.<init>(TldListenerParser.java:45)
5b55a9 SystemErr R at
com.ibm.ws.webcontainer.srt.TldListenerProcessor.<init>(TldListenerProcessor.java:30)
5b55a9 SystemErr R at ... |
|
We can see in the above classloader trace that the class
is loaded from the application's war file. However, in this particular
case, if we search for where this class was loaded in the bootstrap trace,
which is written to native_stdout.log, we can see the following: |
|
[Loaded javax.xml.parsers.SAXParser
from
/export/opt/was51dev/WebSphere/AppServer/java/jre/lib/endorsed/xml.jar]
[Loaded org.apache.xerces.jaxp.JAXPConstants from
/export/opt/was51dev/WebSphere/AppServer/java/jre/lib/endorsed/xml.jar]
[Loaded org.apache.xerces.jaxp.SAXParserImpl from
/export/opt/was51dev/WebSphere/AppServer/java/jre/lib/endorsed/xml.jar]
<-- The SAXParserImpl.class was
loaded on the bootstrap classloader from xml.jar
[Loaded org.apache.xerces.parsers.XMLParser from
/export/opt/was51dev/WebSphere/AppServer/java/jre/lib/endorsed/xml.jar]
[Loaded org.apache.xerces.xni.XMLDocumentHandler from
/export/opt/was51dev/WebSphere/AppServer/java/jre/lib/endorsed/xml.jar] |
|
We can see here that the class was also
loaded from the xml.jar file in "java/jre/lib/endorsed" directory. So we
are trying to load two versions of the class with the same name and that
is causing the ClassCastException. |
|
|
|
|
|
|
Cross Reference information |
Segment |
Product |
Component |
Platform |
Version |
Edition |
Application Servers |
Runtimes for Java Technology |
Java SDK |
|
|
|
|
|
|