简体   繁体   中英

Which classloader loaded a class of the provided instance

In JEE environment it is useful to know, where a particular class is loaded from.

For example I have an instance of org.slf4j.Logger provided by a some black box library. Is it possible to find the responsible classloader? If the class of the instance comes from JDK, Application Server, EAR or Web Application classloader?

It turns out to be quite simple. The name of the classloader is returned by:

object.getClass().getClassLoader().getName()

It returns something like "app" or "platform". Be careful - classloader is null , if the class belongs to the bootstrap classloader, like the JUL logger java.util.logging.Logger does.

WebLogic has a long chain of the classloader without names. WebLogic contains a useful field annotation . One can read it to find the application, the classloader belongs to:

public Object getAnnotation(ClassLoader classloader) {
    try {
        Method amethod = classloader.getClass().getMethod("getAnnotation");
        return amethod.invoke(classloader);
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        return "";
    }
}

If you want to print an overview of all available classloader without digging for annotations, the hashcode of the classloader instance can be used. Here is a small JSP page. Put it into the webapp directory of your web project to get a quick overview.

<%
response.setContentType("text/plain");

List<Class<?>> clazzes = List.of(Logger.class, object.getClass());

out.println("CLASSLOADERS:\n");
ClassLoader classloader = new Object() {}.getClass().getClassLoader();
while (classloader != null) {
    out.println(
            String.format("%-18s", classloader.getName()) + " " +
            String.format("%-10s", Integer.toHexString(classloader.hashCode()))  + " " + 
            classloader.getClass().getName() + " / " + getAnnotation(classloader));

    classloader = classloader.getParent();
}

out.println("\nCLASSES:\n");
for (Class<?> clazz : clazzes) {
    ClassLoader cloader = clazz.getClassLoader();
    URL location = Optional.of(clazz.getProtectionDomain()).map(x->x.getCodeSource()).map(x->x.getLocation()).orElse(null);
    out.println(
            clazz + " \n    " + 
            (cloader != null ? Integer.toHexString(cloader.hashCode()) : "<bootstrap>") + "\t" + 
            location);
}

%>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM