21

我希望在不停止应用程序的情况下分析 Java 应用程序。我可以在应用程序运行时以某种方式添加 Javaagent 吗?

4

4 回答 4

28

请参阅在程序启动后启动 Java 代理

它链接到http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/在“运行时动态加载 javaagent”下提供了工作示例:

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();
}

请注意,Java 9 需要-Djdk.attach.allowAttachSelf=true出现在 JVM 启动参数中。

于 2012-10-23T14:29:34.893 回答
13

您可以使用ea-agent-loader

使用它在运行时加载代理将如下所示:

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!");
    }
}
于 2016-03-03T15:07:58.077 回答
5

根据java.lang.instrument包的文档应该可以。

虚拟机启动后启动代理

实现可以提供一种机制来在 VM 启动后的某个时间启动代理。关于如何启动的细节是特定于实现的,但通常应用程序已经启动并且它的 main 方法已经被调用。如果实现支持在 VM 启动后启动代理,则适用以下情况:

1.agent JAR的manifest必须包含属性Agent-Class。该属性的值是代理类的名称。
2.代理类必须实现一个公共静态agentmain方法。
3. 系统类加载器(ClassLoader.getSystemClassLoader)必须支持将代理JAR 文件添加到系统类路径的机制。

但我从未尝试过:-|

于 2011-01-27T20:59:16.393 回答
1

这里是一个通过注入检测在运行时初始化 aspectj 和 spring-aspects 的库:https ://github.com/subes/invesdwin-instrument

您可以将其用作更精细的示例。

于 2015-08-03T13:16:17.917 回答