java.security.CodeSource; java.security.ProtectionDomain;
  CodeSource 可以给出类的原始URL的位置,但并不是每个类都有CodeSource。如果类通过引导类装载器装载,CodeSource为空。
  import java.lang.reflect.Method; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; 
 public class Debug {
     public static void displayClassInfo(Class clazz, StringBuffer results)    {       displayClassInfo(clazz, results, true);    }    public static void displayClassInfo(Class clazz, StringBuffer results,          boolean showParentClassLoaders)    { 
      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"); 
      results.append("\nImplemented Interfaces:");       Class[] ifaces = clazz.getInterfaces();       for(int i = 0; i < ifaces.length; i ++)       {          Class iface = ifaces[i];          results.append("\n++"+iface+"("+Integer.toHexString(iface.hashCode())+")");          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;    } 
}
   
 
  |