[英]Which classloader loaded a class of the provided instance
在 JEE 环境中,了解特定 class 的加载位置很有用。
例如,我有一个由某个黑盒库提供的org.slf4j.Logger
实例。 是否有可能找到负责的类加载器? 如果实例的 class 来自 JDK、Application Server、EAR 或 Web Application classloader?
事实证明这很简单。 类加载器的名称由以下方式返回:
object.getClass().getClassLoader().getName()
它返回类似“app”或“platform”的东西。 注意 - 类加载器是null
,如果 class 属于引导类加载器,就像 JUL 记录器java.util.logging.Logger
一样。
WebLogic 有一长串没有名称的类加载器。 WebLogic 包含一个有用的字段annotation
。 可以阅读它找到应用程序,类加载器属于:
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);
}
%>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.