本文介绍了如何列出特定类加载器中加载的所有类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于调试原因和好奇心,我希望列出加载到特定类加载器的所有类。

For debug reasons, and curiosity, I wish to list all classes loaded to a specific class loader.

看到类加载器的大多数方法都受到保护,是实现我想要的最佳方式吗?

Seeing as most methods of a class loader are protected, what is the best way to accomplish what I want?

谢谢!

推荐答案

可以做你想做的事。

Instrumentation.getInitiatedClasses(ClassLoader) may do what you want.

根据文档:

我不确定启动装载机是什么意思。如果没有给出正确的结果,请尝试使用 getAllLoadedClasses()方法并手动过滤ClassLoader。

I'm not sure what "initiating loader" means though. If that does not give the right result try using the getAllLoadedClasses() method and manually filtering by ClassLoader.

如何获得仪器的实例

How to get an instance of Instrumentation

只有代理JAR(与应用程序JAR分开)才能获得 Instrumentation 接口的实例。使应用程序可用的一种简单方法是创建一个代理JAR,其中包含一个带有 premain 方法的类,该方法除了保存对 Instrumentation 系统属性中的实例。

Only the agent JAR (which is separate from the application JAR) can get an instance of the Instrumentation interface. A simple way to make it available to the application is to create an agent JAR containing one class with a premain method that does nothing but save a reference to the Instrumentation instance in the system properties.

示例代理类:

public class InstrumentHook {

    public static void premain(String agentArgs, Instrumentation inst) {
        if (agentArgs != null) {
            System.getProperties().put(AGENT_ARGS_KEY, agentArgs);
        }
        System.getProperties().put(INSTRUMENTATION_KEY, inst);
    }

    public static Instrumentation getInstrumentation() {
        return (Instrumentation) System.getProperties().get(INSTRUMENTATION_KEY);
    }

    // Needn't be a UUID - can be a String or any other object that
    // implements equals().
    private static final Object AGENT_ARGS_KEY =
        UUID.fromString("887b43f3-c742-4b87-978d-70d2db74e40e");

    private static final Object INSTRUMENTATION_KEY =
        UUID.fromString("214ac54a-60a5-417e-b3b8-772e80a16667");

}

示例清单:

Manifest-Version: 1.0
Premain-Class: InstrumentHook

然后必须通过命令行中指定的应用程序引用生成的JAR(使用 -javaagent 选项)启动应用程序时。它可能会在不同的 ClassLoader 中加载两次,但这不是问题,因为系统属性是一个处理单例。

The resulting JAR must then be referenced by the application and specified on the command line (with the -javaagent option) when launching the application. It might be loaded twice in different ClassLoaders, but that is not a problem since the system Properties is a per-process singleton.

示例应用程序类

public class Main {
    public static void main(String[] args) {
        Instrumentation inst = InstrumentHook.getInstrumentation();
        for (Class<?> clazz: inst.getAllLoadedClasses()) {
            System.err.println(clazz.getName());
        }
    }
}

这篇关于如何列出特定类加载器中加载的所有类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 06:49