出于调试原因和好奇心,我希望列出所有加载到特定类加载器的类。
鉴于类加载器的大多数方法都受到保护,实现我想要的最佳方法是什么?
谢谢!
[Instrumentation.getInitiatedClasses(ClassLoader)](http://java.sun.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getInitiatedClasses\(java.lang.ClassLoader\)) 可以做你想要的。
[Instrumentation.getInitiatedClasses(ClassLoader)](http://java.sun.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getInitiatedClasses\(java.lang.ClassLoader\))
根据文档:
返回所有类的数组,这些类的加载程序是初始加载程序。
我不确定“启动加载程序”是什么意思。如果这样不能给出正确的结果,请尝试使用该getAllLoadedClasses()方法并通过ClassLoader手动进行过滤。
getAllLoadedClasses()
如何获得的实例Instrumentation
Instrumentation
只有代理JAR(与应用程序JAR分开)可以获取Instrumentation接口的实例。使它可用于应用程序的一种简单方法是使用一种premain方法将其创建为包含一个类的代理JAR,该方法除了Instrumentation在系统属性中保存对实例的引用外不执行任何操作。
premain
代理类示例:
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选项)上指定结果。它可能在不同的ClassLoaders中加载了两次,但这不是问题,因为系统Properties是按进程的单例。
-javaagent
ClassLoader
Properties
示例应用程序类
public class Main { public static void main(String[] args) { Instrumentation inst = InstrumentHook.getInstrumentation(); for (Class<?> clazz: inst.getAllLoadedClasses()) { System.err.println(clazz.getName()); } } }