哪个类加载器加载了所提供实例的类



在JEE环境中,了解特定类的加载位置非常有用。

例如,我有一个由某个黑盒库提供的org.slf4j.Logger实例。有可能找到负责的类加载器吗?如果实例的类来自JDK、ApplicationServer、EAR或Web应用程序类加载器?

事实证明它非常简单。类加载器的名称由返回

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

它返回类似于";应用程序";或";平台";。请注意,如果类属于引导类加载器,则类加载器是null,就像JUL记录器java.util.logging.Logger一样。

WebLogic有一长串没有名字的类加载器。WebLogic的类加载器包含一个有用的字段annotation。可以阅读它来找到JEE应用程序,类加载器属于:

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

如果您想在不挖掘注释的情况下打印所有可用类加载器的概述,那么可以使用类加载器实例的哈希代码。这是一个小的JSP页面。将其放入您的web项目的webapp目录中,以获得快速概述。

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

最新更新