Java Agent与JVMTI在运行时加载,从内部卸载

5
我正在编写一个Java代理程序,与JVMTI交互。由于某些原因,我需要使用JVMTI(在java进程内部的C接口),而不是像java.lang.instrument或JDI这样的Java API。我希望能够做一些似乎不直接支持的事情。
  1. 是否有一种方法在Java进程已经启动后加载代理程序?
  2. 是否有一种方法可以卸载Java代理程序(除了杀死整个Java进程),无论是从JVMTI代码内部还是从进程外部?例如,如果我可以找到动态加载模块的句柄,我能否从JVMTI代码中安全地调用dlclose()

如果这些操作无法完成,是否有一种方法在加载代理程序后向Java代理程序传递数据?是否有一种通过某些Java命令行实用程序正常完成此操作的方法?如果没有,我能否在我的代理程序代码中使用标准的C或C++库调用创建一个线程并使其侦听套接字?

如果方便的话,不用担心你的回答是否支持Windows - 我正在进行这个项目来扩展一个仅限于Unix的调试工具。
注意:我已经看过this,但是认为可能有一些常规方法可以做到这一点,而这些方法不在JVMTI标准中。
1个回答

5
  1. 您只能在JVM的启动时间通过传递参数 -agentlib:<agent-lib-name>=<options> 或者 -agentpath:<path-to-agent>=<options> 来注入(部署)一个代理。

    另一种方法是通过Java本身来实现。这严重依赖于JVM,因此超出了JVMTI规范的范围。例如,如果有VirtualMachine类,可以通过方法loadAgentPath(agentPath, options)来实现。如果您想从本地JVMTI代码中执行此操作,则需要进行字节码插装。

  2. 我不确定,与第1点类似,您可以通过字节码插装运行Java的unload方法。如果dlclose()可用,我认为这样做没有问题。

正如你所看到的,你可以使用选项将数据传递给Java代理。或者,如果你想在两个实例之间持续传递数据,你可以打开两个套接字并在它们之间进行写入/读取。我使用了Protobuf


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接