论坛首页 Java企业应用论坛

调试ClassLoader问题

浏览 4930 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-05-10  
好像作J2EE开发的人都中过ClassLoader的招,会碰到ClassCastException/LinkageException之类的奇怪的东东
如果是JBoss的话,JBoss的JMX可以帮助调试,

打开http://localhost:8080/jmx-console, 点name=Default,service=LoaderRepository,

这个MBean有蛮多函数,其中最重要的一个是
displayClassInfo()
填入要看的Class类名,比如org.apache.tapestry.ApplicationServlet,

点Invoke,出来以下信息:

org.apache.tapestry.ApplicationServlet Information
Repository cache version:
org.apache.tapestry.ApplicationServlet(954549).ClassLoader=org.jboss.mx.loading.UnifiedClassLoader3@1ccbefe{ url=file:/E:/jboss/server/default/tmp/deploy/tmp25612vlib.ear ,addedOrder=33}..org.jboss.mx.loading.UnifiedClassLoader3@1ccbefe{ url=file:/E:/jboss/server/default/tmp/deploy/tmp25612vlib.ear ,addedOrder=33}
..org.jboss.system.server.NoAnnotationURLClassLoader@a83b8a
..sun.misc.Launcher$AppClassLoader@92e78c
....file:/E:/jboss/bin/
....file:/C:/j2sdk1.4.1_02/lib/tools.jar
....file:/E:/jboss/bin/run.jar
..sun.misc.Launcher$ExtClassLoader@9fbe93
....file:/C:/j2sdk1.4.1_02/jre/lib/ext/dnsns.jar
....file:/C:/j2sdk1.4.1_02/jre/lib/ext/ldapsec.jar
....file:/C:/j2sdk1.4.1_02/jre/lib/ext/localedata.jar
....file:/C:/j2sdk1.4.1_02/jre/lib/ext/sunjce_provider.jar
++++CodeSource: (file:/E:/jboss/server/default/tmp/deploy/tmp25612vlib.ear-contents/vlibbeans.jar-contents/tapestry-3.0-rc-1.jar )
Implemented Interfaces:

### Instance0 found in UCL: org.jboss.mx.loading.UnifiedClassLoader3@1ccbefe{ url=file:/E:/jboss/server/default/tmp/deploy/tmp25612vlib.ear ,addedOrder=33}


重要的地方特地加黑了,可以看到,他显示了要看的类的ClassLoader以及Load的位置(CodeSource),当然还显示了ClassLoader 的hierarchy结构,

如果某个ClassLoader是URLClassLoader(sun.misc.Launcher$AppClassLoader和sun.misc.Launcher$ExtClassLoader都是URLClassLoader的子类),还能显示对应能Load的URL信息(这里都是file://什么的)

另外,上面打得测试代码主要是从org.jboss.test.util.Debug来,可以参考,在其它需要调试ClassLoader的地方也可以用的着。

ps,自己目前只用Web Container(Jetty),不知道Jetty有没有类似的辅助调试功能,要找找看:)。
   发表时间:2004-05-10  
ps:感觉JMX技术还是蛮有用的一个东东,有机会研究研究,可以通过HTML页面
直接查看MBean的状态和调用MBean的服务,想起Web Service也是想把操作暴露
出来的,不知道能不能在HTML页面上直接调用。
另外Debug那个代码蛮有用的,干脆贴出来:
package org.jboss.test.util;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
/** Various debugging utility methods available for use in unit tests
* @author Scott.Stark@jboss.org
*/
public class Debug
{
   /** Format a string buffer containing the Class, Interfaces, CodeSource,
    and ClassLoader information for the given object clazz.
    @param clazz the Class
    @param results, the buffer to write the info to
    */
   public static void displayClassInfo(Class clazz, StringBuffer results)
   {
      // Print out some codebase info for the ProbeHome
      ClassLoader cl = clazz.getClassLoader();
      results.append("\n"+clazz.getName()+".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( parent != null )
            parent = parent.getParent();
      }
      CodeSource clazzCS = clazz.getProtectionDomain().getCodeSource();
      if( clazzCS != null )
         results.append("\n++++CodeSource: "+clazzCS);
      else
         results.append("\n++++Null CodeSource");
      results.append("\nImplemented Interfaces:");
      Class[] ifaces = clazz.getInterfaces();
      for(int i = 0; i < ifaces.length; i ++)
      {
         results.append("\n++"+ifaces[i]);
         ClassLoader loader = ifaces[i].getClassLoader();
         results.append("\n++++ClassLoader: "+loader);
         ProtectionDomain pd = ifaces[i].getProtectionDomain();
         CodeSource cs = pd.getCodeSource();
         if( cs != null )
            results.append("\n++++CodeSource: "+cs);
         else
            results.append("\n++++Null CodeSource");
      }
   }
   /** Use reflection to access a URL[] getURLs or ULR[] getAllURLs method so
    that non-URLClassLoader class loaders, or class loaders that override
    getURLs to return null or empty, can provide the true classpath info.
    */
   public static URL[] getClassLoaderURLs(ClassLoader cl)
   {
      URL[] urls = {};
      try
      {
         Class returnType = urls.getClass();
         Class[] parameterTypes = {};
         Method getURLs = cl.getClass().getMethod("getURLs", parameterTypes);
         if( returnType.isAssignableFrom(getURLs.getReturnType()) )
         {
            Object[] args = {};
            urls = (URL[]) getURLs.invoke(cl, args);
         }
      }
      catch(Exception ignore)
      {
      }
      return urls;
   }
  
}
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics