package org.jboss.cache.marshall.data;
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, StringBuilder results)
{
displayClassInfo(clazz, results, true);
}
@SuppressWarnings("null")
public static void displayClassInfo(Class clazz, StringBuilder 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;
}
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<? extends URL[]> 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;
}
}