简体   繁体   English

程序启动后启动 Java 代理

[英]Starting a Java agent after program start

Is it possible to insert a javaagent after virtual machine start from within the same VM?是否可以在虚拟机从同一 VM 内启动后插入 javaagent?

Lets say for example we have an agent in a jar myagent.jar with the appropriate meta data set-up and an agentmain method already implemented.例如,我们在 jar myagent.jar 中有一个代理,具有适当的元数据设置和已经实现的 agentmain 方法。 Now the users program calls an API call which should result in the insertion of the agent so that it can redefine the classes.现在,用户程序调用一个 API 调用,这将导致插入代理,以便它可以重新定义类。

Can it be done and how?可以做到吗?如何做到?

Yes, you just have to pass the JVM process ID to the VirtualMachine.attach(String pid) method, and load the agent jar.是的,您只需要将 JVM 进程 ID 传递给VirtualMachine.attach(String pid)方法,然后加载代理 jar。 The VirtualMachine class is available in the JDK_HOME/lib/tools.jar file. VirtualMachine类在 JDK_HOME/lib/tools.jar 文件中可用。 Here's an example of how I activate an agent at runtime:这是我如何在运行时激活代理的示例:

public static void attachGivenAgentToThisVM(String pathToAgentJar) {
  try {                                                                               
    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();                                                   
    String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));                                                   
    VirtualMachine vm = VirtualMachine.attach(pid);                                                                            
    vm.loadAgent(pathToAgentJar, "");
    vm.detach();   
  } catch (Exception e) {
    e.printStackTrace();
  }
}                                                                                                            

You should be able to do it in Java 6, see the package documentation chapter "Starting Agents After VM Startup"您应该可以在 Java 6 中执行此操作,请参阅包文档章节“VM 启动后启动代理”

edit: Maybe it was possible in Java 5 already and just the javadocs didn't mention it that explicitly编辑:也许在 Java 5 中已经有可能了,只是 javadocs 没有明确提到它

Having encountered the same issue, I have found a far more comprehensive solution, from the ByteBuddy library .遇到同样的问题后,我从 ByteBuddy 库中找到了一个更全面的解决方案。

ByteBuddy thoroughly attempts to load its java agent dynamically: ByteBuddy 彻底尝试动态加载其 Java 代理:

Installs an agent on the currently running Java virtual machine.在当前运行的 Java 虚拟机上安装代理。 Unfortunately, this does not always work.不幸的是,这并不总是有效。 The runtime installation of a Java agent is supported for:支持 Java 代理的运行时安装:

  • JVM version 9+ : For Java VM of at least version 9, the attachment API was moved into a module and the runtime installation is possible if the {@code jdk.attach} module is available to Byte Buddy which is typically only available for VMs shipped with a JDK. JVM 版本 9+ :对于至少版本 9 的 Java VM,附件 API 被移到一个模块中,并且如果 {@code jdk.attach} 模块可用于 Byte Buddy 模块(通常仅可用于 VM),则运行时安装是可能的附带一个 JDK。
  • OpenJDK / Oracle JDK / IBM J9 versions 8- : The installation for HotSpot is only possible when bundled with a JDK and requires a {@code tools.jar} bundled with the VM which is typically only available for JDK-versions of the JVM. OpenJDK / Oracle JDK / IBM J9 版本 8- :HotSpot 的安装只有在与 JDK 捆绑在一起时才可能安装,并且需要与 VM 捆绑在一起的 {@code tools.jar},这通常仅适用于 JVM 的 JDK 版本。
  • When running Linux and including the optional junixsocket-native-common dependency, Byte Buddy emulates a Unix socket connection to attach to the target VM.当运行 Linux 并包含可选的junixsocket-native-common依赖项时,Byte Buddy 会模拟 Unix 套接字连接以附加到目标 VM。
  • 声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM