程序启动后启动Java代理程序
是否可以在虚拟机启动后从同一VM中插入javaagent?程序启动后启动Java代理程序
比方说,例如我们在jar myagent.jar中有一个代理,其中已经实现了适当的元数据设置和agentmain方法。现在用户程序调用一个API调用,该调用应该导致代理的插入,以便它可以重新定义这些类。
可以这样做吗?
https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/有一个很好的例子,如何写一个代理以及如何在飞行中启动一个。
链接示例不完整,不起作用。 – 2013-04-24 18:31:46
这并不意味着是一个独立的教程,是真的。但它对于高级Java开发人员来说是一个很好的例子。我个人对这个例子没有任何问题。 – 2013-04-25 16:18:18
链接已损坏。我能够在WayBackMachine上找到它的存档:https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with -javaagents/ – 11101101b 2014-10-29 21:40:18
是的,您只需将JVM进程ID传递给VirtualMachine.attach(String pid)
方法,然后加载代理jar。 VirtualMachine
类在JDK_HOME/lib/tools.jar文件中可用。以下是我如何在运行时激活代理的示例:
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();
}
}
但它没有指定方法调用的内容。进一步研究它会((URLClassLoader)ClassLoader.getSystemClassLoader())。addURL(....)添加的URL指向myagent.jar结果在agentmain被调用? – 2009-08-14 11:50:39
这是一般的Java 6还是仅适用于HotSpot? – 2009-08-14 13:35:31
@保罗:我没有尝试过,所以我不能说它是否像那样工作,但它似乎是合理的。但是,您必须通过反射来调用addURL,因为它受到保护。 类似于: URLClassLoader sysloader =(URLClassLoader)ClassLoader.getSystemClassLoader(); \t Class sysclass = URLClassLoader.class; \t尝试{ \t \t Method method = sysclass.getDeclaredMethod(“addURL”,parameters); \t \t method.setAccessible(true); method.invoke(sysloader,new Object [] {yourURL}); \t} – HerdplattenToni 2009-08-17 10:25:43