Starting a Java agent after program start

18,864

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

Share:
18,864

Related videos on Youtube

Paul Keeble
Author by

Paul Keeble

An independent programmer in London working on highly scalable transparent object storage systems.

Updated on September 02, 2020

Comments

  • Paul Keeble
    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
    matbrgz almost 15 years
    Is this Java 6 in general or only with HotSpot?
  • HerdplattenToni
    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
    Alan Cabrera about 11 years
    It'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
    11101101b over 9 years
    The link is broken. I was able to find it archived on the WayBackMachine: web.archive.org/web/20141014195801/http://dhruba.name/2010/0‌​2/…
  • hrishikeshp19
    hrishikeshp19 over 9 years
    that link does not work anymore. you should have copied content and pasted here.
  • madhu
    madhu about 9 years
    thanks 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
    pierpytom about 9 years
    I 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
    Alan Cabrera about 8 years
    The wayback link should suffice
  • Sam Thomas
    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>(LinuxVirtualMach‌​ine.java:106) at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(Li‌​nuxAttachProvider.ja‌​va:63) at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.ja‌​va:208) at Main.main(Main.java:15)
  • Sam Thomas
    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>(LinuxVirtualMach‌​ine.java:106) at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(Li‌​nuxAttachProvider.ja‌​va:63) at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.ja‌​va:208) at Main.main(Main.java:15)
  • Sam Thomas
    Sam Thomas about 6 years
    I have tried this on CentOS and Ubuntu. Both failed the same way
  • Sam Thomas
    Sam Thomas about 6 years
    I have tried this on CentOS and Ubuntu. Both failed the same way
  • Ashok Waghmare
    Ashok Waghmare over 5 years
    It needs tools.jar, is it worth adding tools.jar in class path. (using Java8)