是否可以通过 Java 1.6 attach api 获取加载到当前 JVM 中的代理列表?如果有怎么办?
启动时加载的代理可以通过 RuntimeMXBean 确定,但我看不到一种方法来处理启动后添加的代理。
是否可以通过 Java 1.6 attach api 获取加载到当前 JVM 中的代理列表?如果有怎么办?
启动时加载的代理可以通过 RuntimeMXBean 确定,但我看不到一种方法来处理启动后添加的代理。
(这个问题类似于How to find list of java agents attach with a running JVM?。为了完整起见,我将在这两个问题中添加这个答案。)
如果您对在运行时使用 Attach API 添加到应用程序的代理感兴趣,您可以使用DiagnosticCommandMBean
. 这个 bean 提供了一个名为 的诊断命令vmDynlib
,这是一个无参数的方法,它返回一个String
列出所有动态加载的库的列表。
这是打印应用程序 VM 加载的所有动态库的代码段:
ObjectName diagnosticsCommandName = new ObjectName("com.sun.management:type=DiagnosticCommand");
String operationName = "vmDynlibs";
String result = (String) ManagementFactory.getPlatformMBeanServer().invoke(diagnosticsCommandName, operationName, null, null);
System.out.println(result);
这会产生与此类似的输出:
Dynamic libraries:
0x00007ff7b8600000 - 0x00007ff7b8637000 C:\Program Files\Java\jdk1.8.0_181\bin\java.exe
0x00007ffdfeb00000 - 0x00007ffdfecf0000 C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffdfe300000 - 0x00007ffdfe3b2000 C:\WINDOWS\System32\KERNEL32.DLL
0x00007ffdfbb30000 - 0x00007ffdfbdd3000 C:\WINDOWS\System32\KERNELBASE.dll
0x00007ffdfe950000 - 0x00007ffdfe9f3000 C:\WINDOWS\System32\ADVAPI32.dll
...
然后,您可以检查此文本是否包含某个文件.so
或.dll
文件。
可以以非编程方式执行相同的检查。
为此,您可以使用该jconsole
工具。
连接到虚拟机,切换到选项卡MBeans
,选择com.sun.management
、选择DiagnosticCommand
、选择Operations
、选择vmDynlibs
并调用它。
在图像中,您可以看到我的一个测试代理附加到应用程序。该代理是使用 附加的Attach API
,因此通过检查应用程序的命令行参数将不会看到该代理(即,不会-agentpath=...
在参数上看到),但仅作为动态加载的库可见。
为了获得完整的参考,我还将发布如何检测已通过命令行添加的代理。您可以使用RuntimeMXBean
.
该 bean 提供方法getInputArguments
,它返回所有 VM 参数的列表。您可以遍历列表并检查它的参数agentpath
,agentlib
和javaagent
,类似于以下代码片段:
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeMXBean.getInputArguments();
System.out.println("JVM arguments:");
for (String arg : jvmArgs) {
if (arg.startsWith("-agentpath") || arg.startsWith("-agentlib") || arg.startsWith("-javaagent")) {
System.out.print("***** ");
}
System.out.print(arg);
if (arg.startsWith("-agentpath") || arg.startsWith("-agentlib") || arg.startsWith("-javaagent")) {
System.out.println(" *****");
} else {
System.out.println();
}
}
不,我认为没有一种可移植的方式来了解代理。你想达到什么目的?也许还有另一种方法...