8

是否可以通过 Java 1.6 attach api 获取加载到当前 JVM 中的代理列表?如果有怎么办?

启动时加载的代理可以通过 RuntimeMXBean 确定,但我看不到一种方法来处理启动后添加的代理。

4

2 回答 2

3

(这个问题类似于How to find list of java agents attach with a running JVM?。为了完整起见,我将在这两个问题中添加这个答案。)


检查已使用 Attach API 添加的代理:

如果您对在运行时使用 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并调用它。

vmDynlibs 输出

在图像中,您可以看到我的一个测试代理附加到应用程序。该代理是使用 附加的Attach API,因此通过检查应用程序的命令行参数将不会看到该代理(即,不会-agentpath=...在参数上看到),但仅作为动态加载的库可见。

检查已通过命令行添加的代理:

为了获得完整的参考,我还将发布如何检测已通过命令行添加的代理。您可以使用RuntimeMXBean.

该 bean 提供方法getInputArguments,它返回所有 VM 参数的列表。您可以遍历列表并检查它的参数agentpath,agentlibjavaagent,类似于以下代码片段:

    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();
        }
    }
于 2019-09-09T13:04:43.683 回答
1

不,我认为没有一种可移植的方式来了解代理。你想达到什么目的?也许还有另一种方法...

于 2011-08-02T17:09:27.767 回答