如何在不停止JVM的情况下添加Java代理?

24

我希望在不停止Java应用程序的情况下对其进行分析。请问我是否可以在应用程序运行时添加Java代理?


我曾多次希望能够在生产环境中附加调试器... - omerkudat
@omerkudat 哎呀 :). 然后使用调试器选项运行它,你不会看到任何真正的性能损失,但调试器可能会导致泄漏。 - bestsss
那么调试器选项是否允许我在运行时添加Java代理? - yazzapps.com
@Thorbjørn Ravn Andersen:你可以这样称呼它们(洞),但是我通常不认为洞是我故意做的,并且非常清楚它的作用。 - bestsss
@bestsss,也许你不知道。在一个应用程序(注意:不是应用服务器)运行在客户机器上,同时还有其他职责的世界中,通常不能容忍这种情况出现在生产代码中。 - Thorbjørn Ravn Andersen
显示剩余7条评论
4个回答

30

请参见Starting a Java agent after program start

该链接指向 http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ 页面,在“Dynamic loading of a javaagent at runtime”一节中提供了可行的示例:

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需要在JVM启动参数中添加-Djdk.attach.allowAttachSelf=true


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!");
    }
}

我检查了ea-agent-loader,它看起来非常不错。可悲的是它对我不起作用:https://stackoverflow.com/questions/48678557/how-to-start-aspectj-loadtime-weaver-agent-without-restarting-jvm-how-to-start和https://github.com/electronicarts/ea-agent-loader/issues/9 - cilap

6
根据java.lang.instrument包的文档,应该可以实现。

在VM启动后启动代理

实现可能会提供一种机制,在VM启动后的某个时刻启动代理。如何启动代理是特定于实现的,但通常应用程序已经启动,它的主方法已经被调用。在实现支持在VM启动后启动代理的情况下,以下内容适用:

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

但我从未尝试过 :-|


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接