Starting a Java agent after program start
Solution 1
https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ has a great example of how to write an agent as well as how to start one on the fly.
Solution 2
Yes, you just have to pass the JVM process ID to the VirtualMachine.attach(String pid)
method, and load the agent jar. The VirtualMachine
class is available in the JDK_HOME/lib/tools.jar file. 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();
}
}
Solution 3
You should be able to do it in Java 6, see the package documentation chapter "Starting Agents After VM Startup"
edit: Maybe it was possible in Java 5 already and just the javadocs didn't mention it that explicitly
Related videos on Youtube
Paul Keeble
An independent programmer in London working on highly scalable transparent object storage systems.
Updated on September 02, 2020Comments
-
Paul Keeble almost 4 years
Is it possible to insert a javaagent after virtual machine start from within the same VM?
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. Now the users program calls an API call which should result in the insertion of the agent so that it can redefine the classes.
Can it be done and how?
-
matbrgz almost 15 yearsIs this Java 6 in general or only with HotSpot?
-
HerdplattenToni almost 15 years@Paul: I haven't tried it so I can't say if it works like that but it seems reasonable. However you will have to call addURL by reflection since it is protected. Something like: URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader(); Class sysclass = URLClassLoader.class; try { Method method = sysclass.getDeclaredMethod("addURL",parameters); method.setAccessible(true); method.invoke(sysloader,new Object[]{ yourURL }); }
-
Alan Cabrera about 11 yearsIt's not meant to be a self contained tutorial, true. But it is a great example for advanced Java developers. I, personally, had no problem with the example.
-
11101101b over 9 yearsThe link is broken. I was able to find it archived on the WayBackMachine: web.archive.org/web/20141014195801/http://dhruba.name/2010/02/…
-
hrishikeshp19 over 9 yearsthat link does not work anymore. you should have copied content and pasted here.
-
madhu about 9 yearsthanks for good answer. but when i am trying the same but i got an exception ** com.sun.tools.attach.AgentLoadException: Agent JAR not found or no Agent-Class attribute **
-
pierpytom about 9 yearsI suspect it's a dependency issue, here how to solve in maven: m.blog.csdn.net/blog/chendeng8899/8487336 ("Dynamic loading of a javaagent at runtime" section)
-
Alan Cabrera about 8 yearsThe wayback link should suffice
-
Sam Thomas about 6 years@AlanCabrera I'm using jdk 1.8. I have tried oracle and openjdk, but I never can attach to the jvm. The attempt causes a threaddump in the target jvm and fails on the injecting jvm saying com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:106) at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63) at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208) at Main.main(Main.java:15)
-
Sam Thomas about 6 years@11101101b I'm using jdk 1.8. I have tried oracle and openjdk, but I never can attach to the jvm. The attempt causes a threaddump in the target jvm and fails on the injecting jvm saying com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:106) at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63) at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208) at Main.main(Main.java:15)
-
Sam Thomas about 6 yearsI have tried this on CentOS and Ubuntu. Both failed the same way
-
Sam Thomas about 6 yearsI have tried this on CentOS and Ubuntu. Both failed the same way
-
Ashok Waghmare over 5 yearsIt needs tools.jar, is it worth adding tools.jar in class path. (using Java8)