23

I wish to profile a Java application without stopping the application. Can I add a Javaagent somehow while the application is running?

Vadzim
  • 24,954
  • 11
  • 143
  • 151
yazz.com
  • 57,320
  • 66
  • 234
  • 385
  • The times I wished I could attach the debugger in production... – omerkudat Jan 27 '11 at 14:42
  • @omerkudat ouchy :). Then run it w/ the debugger option, you wont see any real performance drawback, but debuggers can cause leaks – bestsss Jan 27 '11 at 14:48
  • So does the debugger option allow me to add a javaagent at runtime? – yazz.com Jan 27 '11 at 15:46
  • @bestsss: They also can be a security vulnerability. – Lawrence Dol Jan 27 '11 at 17:15
  • @Software Monkey - hardly security vulnerability - block the port and allow it only for a few selected IPs prior attaching the debugger. – bestsss Jan 27 '11 at 17:52
  • @bestsss: That you have to take additional action to block the port illustrates it's a potential security vulnerability. – Lawrence Dol Jan 27 '11 at 18:37
  • @Software Monkey: sure it is, but it's easily solved. Yet, running almost any Application Server on Java opens a good number of ports, so taking care of debugger is no different. That was my point, opening the debugger port to the world is asking for a trouble (although the port is not standard), so is RMI one and so on. – bestsss Jan 27 '11 at 19:12
  • @bestsss, debug ports are security holes if ever there was one! – Thorbjørn Ravn Andersen Jan 27 '11 at 19:20
  • @Zubair, debugger option does _not_ allow for attaching a javaagent. – Thorbjørn Ravn Andersen Jan 27 '11 at 19:22
  • @Thorbjørn Ravn Andersen: you can call 'em like that (hole) but I, generally, don't consider a hole something that I have done on purpose and am very well aware what it does. – bestsss Jan 27 '11 at 19:31
  • @bestsss, perhaps you do not. In a world where the applications (note: not app servers) run on customer machinery which happens to have other responsibilities too, it is usually unacceptable to have this into code running in production. – Thorbjørn Ravn Andersen Jan 27 '11 at 19:45
  • @Thorbjørn Ravn Andersen: that's a weird statement, the remark about debugging was mentioned to omerkudat and no one has talked about client machines at all. I'd not even consider connecting to anything not exclusively owned, unless explicitly asked by a customer and even then it would be just sending back logs. – bestsss Jan 27 '11 at 19:59

4 Answers4

29

See Starting a Java agent after program start.

It links to http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ that under "Dynamic loading of a javaagent at runtime" provides working example:

public static void loadAgent() throws Exception {
    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
    String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));
    VirtualMachine vm = VirtualMachine.attach(pid);
    vm.loadAgent(jarFilePath, "");
    vm.detach();
}

Note that Java 9 requires -Djdk.attach.allowAttachSelf=true to be present among JVM startup arguments.

Vadzim
  • 24,954
  • 11
  • 143
  • 151
13

You can use ea-agent-loader

With it loading an agent in runtime will look like:

public class HelloAgentWorld
{
    public static class HelloAgent
    {
        public static void agentmain(String agentArgs, Instrumentation inst)
        {
            System.out.println(agentArgs);
            System.out.println("Hi from the agent!");
            System.out.println("I've got instrumentation!: " + inst);
        }
    }

    public static void main(String[] args)
    {
        AgentLoader.loadAgentClass(HelloAgent.class.getName(), "Hello!");
    }
}
Daniel Sperry
  • 4,381
  • 4
  • 31
  • 41
  • I checked the ea-agent-loader, which looks pretty good. Sadly it is not working for me: https://stackoverflow.com/questions/48678557/how-to-start-aspectj-loadtime-weaver-agent-without-restarting-jvm-how-to-start and here https://github.com/electronicarts/ea-agent-loader/issues/9 – cilap Feb 08 '18 at 05:58
6

It should be possible according the documentation of the java.lang.instrument package.

Starting Agents After VM Startup

An implementation may provide a mechanism to start agents sometime after the the VM has started. The details as to how this is initiated are implementation specific but typically the application has already started and its main method has already been invoked. In cases where an implementation supports the starting of agents after the VM has started the following applies:

1.The manifest of the agent JAR must contain the attribute Agent-Class. The value of this attribute is the name of the agent class.
2. The agent class must implement a public static agentmain method.
3. The system class loader ( ClassLoader.getSystemClassLoader) must support a mechanism to add an agent JAR file to the system class path.

but I have never tried it :-|

user85421
  • 28,957
  • 10
  • 64
  • 87
1

Here a library that initializes aspectj and spring-aspects at runtime by injecting instrumentation: https://github.com/subes/invesdwin-instrument

You can use it as a more elaborate sample.

subes
  • 1,832
  • 5
  • 22
  • 28