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; }
}

|