哪个类加载器加载了所提供实例的类
在JEE环境中,了解特定类的加载位置非常有用。
例如,我有一个由某个黑匣子库提供的org.slf4j.Logger
实例。有可能找到负责的类加载器吗?如果实例的类来自JDK、应用服务器、EAR或Web应用程序类加载器?
解决方案
原来很简单。类加载器的名称由:
返回object.getClass().getClassLoader().getName()
它返回类似于&q;app&q;或&q;Platform&q;之类的内容。请注意--如果类属于引导类加载器,则类加载器是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:
");
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("
CLASSES:
");
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 + "
" +
(cloader != null ? Integer.toHexString(cloader.hashCode()) : "<bootstrap>") + " " +
location);
}
%>
相关文章