JBoss.org Community Documentation
Debugging class loading issues comes down to finding out where a class was loaded from. A useful tool for this is the code snippet shown in Example 3.7, “Obtaining debugging information for a Class” taken from the org.jboss.util.Debug class of the book examples.
Class clazz =...; StringBuffer results = new StringBuffer(); ClassLoader cl = clazz.getClassLoader(); results.append("\n" + clazz.getName() + "(" + Integer.toHexString(clazz.hashCode()) + ").ClassLoader=" + cl); ClassLoader parent = cl; while (parent != null) { results.append("\n.."+parent); URL[] urls = getClassLoaderURLs(parent); int length = urls != null ? urls.length : 0; for(int u = 0; u < length; u ++) { results.append("\n...."+urls[u]); } if (showParentClassLoaders == false) { break; } if (parent != null) { parent = parent.getParent(); } } CodeSource clazzCS = clazz.getProtectionDomain().getCodeSource(); if (clazzCS != null) { results.append("\n++++CodeSource: "+clazzCS); } else { results.append("\n++++Null CodeSource"); }
Example 3.7. Obtaining debugging information for a Class
The key items are shown in bold. The first is that every Class object knows its defining ClassLoader
and this is available via the getClassLoader()
method. The defines the scope in which the Class
type is known as we have just seen in the previous sections on class cast exceptions, illegal access exceptions and linkage errors. From the ClassLoader
you can view the hierarchy of class loaders that make up the parent delegation chain. If the class loader is a URLClassLoader
you can also see the URLs used for class and resource loading.
The defining ClassLoader
of a Class
cannot tell you from what location that Class
was loaded. To determine this you must obtain the java.security.ProtectionDomain
and then the java.security.CodeSource
. It is the CodeSource
that has the URL p location from which the class originated. Note that not every Class
has a CoPdeSource
. If a class is loaded by the bootstrap class loader then its CodeSource
will be null. This will be the case for all classes in the java.*
and javax.*
packages, for example.
Beyond that it may be useful to view the details of classes being loaded into the JBoss server. You can enable verbose logging of the JBoss class loading layer using a Log4j configuration fragment like that shown in Example 3.8, “An example log4j.xml configuration fragment for enabling verbose class loading logging”.
<appender name="UCL" class="org.apache.log4j.FileAppender"> <param name="File" value="${jboss.server.home.dir}/log/ucl.log"/> <param name="Append" value="false"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%r,%c{1},%t] %m%n"/> </layout> </appender> <category name="org.jboss.mx.loading" additivity="false"> <priority value="TRACE" class="org.jboss.logging.XLevel"/> <appender-ref ref="UCL"/> </category>
Example 3.8. An example log4j.xml configuration fragment for enabling verbose class loading logging
This places the output from the classes in the org.jboss.mx.loading
package into the ucl.log
file of the server configurations log directory. Although it may not be meaningful if you have not looked at the class loading code, it is vital information needed for submitting bug reports or questions regarding class loading problems.