Reputation: 11406
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?
Upvotes: 3
Views: 281
Reputation: 11406
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 classloaders without names. WebLogic's classloaders contain a useful field annotation
. One can read it to find the JEE 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);
}
%>
Upvotes: 2