繁体   English   中英

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

[英]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.

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