在程序启动后启动Java代理
在虚拟机从同一个VM中启动之后,是否可以插入javaagent 比如说,我们在jar myagent.jar中有一个代理,它具有适当的元数据设置,并且已经实现了一个agentmain方法。现在,用户程序调用一个API调用,这将导致插入代理,以便重新定义类在程序启动后启动Java代理,java,javaagents,Java,Javaagents,在虚拟机从同一个VM中启动之后,是否可以插入javaagent 比如说,我们在jar myagent.jar中有一个代理,它具有适当的元数据设置,并且已经实现了一个agentmain方法。现在,用户程序调用一个API调用,这将导致插入代理,以便重新定义类 可以这样做吗?如何做?您应该能够在Java 6中这样做,请参阅“VM启动后启动代理”一章 编辑:也许在Java 5中已经有可能了,只是javadocs没有明确提到,有一个关于如何编写代理以及如何动态启动代理的好例子。是的,您只需将JVM进程ID
可以这样做吗?如何做?您应该能够在Java 6中这样做,请参阅“VM启动后启动代理”一章
编辑:也许在Java 5中已经有可能了,只是javadocs没有明确提到,有一个关于如何编写代理以及如何动态启动代理的好例子。是的,您只需将JVM进程ID传递给
VirtualMachine.attach(String pid)
方法,然后加载代理jar。JDK_HOME/lib/tools.jar文件中提供了VirtualMachine
类。以下是如何在运行时激活代理的示例:
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();
}
}
遇到同样的问题后,我找到了一个更全面的解决方案 ByteBuddy尝试动态加载其java代理: 在当前运行的Java虚拟机上安装代理。不幸的是,这并不总是有效的。Java代理的运行时安装受以下支持:
但是,它没有指定方法调用是什么。然而,进一步研究它会((URLClassLoader)ClassLoader.getSystemClassLoader()).addURL(..)其中添加的URL指向myagent.jar,导致调用agentmain?这是一般的Java 6还是只使用热点?@Paul:我没有尝试过,所以我不能说它是否这样工作,但它似乎合理。但是,您必须通过反射调用addURL,因为它是受保护的。类似于:URLClassLoader sysloader=(URLClassLoader)ClassLoader.getSystemClassLoader();类sysclass=URLClassLoader.Class;试试{Method Method=sysclass.getDeclaredMethod(“addURL”,参数);Method.setAccessible(true);Method.invoke(sysloader,新对象[]{yourURL});}这不是一个自包含的教程,true。但对于高级Java开发人员来说,这是一个很好的例子。一、 就我个人而言,我对这个例子没有任何问题。链接断了。我能在Wayback机器上找到它的存档:这个链接不再起作用了。你应该复制内容并粘贴到这里。回程链接应该suffice@AlanCabrera我正在使用JDK1.8。我曾经尝试过oracle和openjdk,但我永远无法连接到jvm。该尝试在目标jvm中导致线程转储,并在注入jvm上失败,如com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或热点VM未在sun.tools.attach.LinuxVirtualMachine上加载。(LinuxVirtualMachine.java:106)在com.sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)在com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)在Main.Main(Main.java:15)感谢您的回答。但是当我尝试同样的方法时,我得到了一个异常**com.sun.tools.attach.AgentLoadException:Agent JAR找不到或没有Agent Class属性**我怀疑这是一个依赖性问题,这里如何在maven中解决:(“运行时动态加载javaagent”部分)@11101101b我使用的是jdk 1.8。我曾经尝试过oracle和openjdk,但我永远无法连接到jvm。该尝试在目标jvm中导致线程转储,并在注入jvm上失败,如com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或热点VM未在sun.tools.attach.LinuxVirtualMachine上加载。(LinuxVirtualMachine.java:106)在com.sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)在com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)在Main.Main(Main.java:15)我已经在CentOS和Ubuntu上试过了。两者都以同样的方式失败了它需要tools.jar,是否值得在类路径中添加tools.jar。(使用Java8)