是否可以在虛擬機啓動後從同一VM中插入javaagent?程序啓動後啓動Java代理程序
比方說,例如我們在jar myagent.jar中有一個代理,其中已經實現了適當的元數據設置和agentmain方法。現在用戶程序調用一個API調用,該調用應該導致代理的插入,以便它可以重新定義這些類。
可以這樣做嗎?
是否可以在虛擬機啓動後從同一VM中插入javaagent?程序啓動後啓動Java代理程序
比方說,例如我們在jar myagent.jar中有一個代理,其中已經實現了適當的元數據設置和agentmain方法。現在用戶程序調用一個API調用,該調用應該導致代理的插入,以便它可以重新定義這些類。
可以這樣做嗎?
你應該能夠做到這一點在Java 6中,看到了package documentation章「啓動代理VM啓動後」
編輯:也許它在Java 5中有可能已經和剛剛的javadoc沒有提到它那明確
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