我希望在不停止应用程序的情况下分析 Java 应用程序。我可以在应用程序运行时以某种方式添加 Javaagent 吗?
4 回答
请参阅在程序启动后启动 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 启动参数中。
您可以使用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!");
}
}
根据java.lang.instrument包的文档应该可以。
虚拟机启动后启动代理
实现可以提供一种机制来在 VM 启动后的某个时间启动代理。关于如何启动的细节是特定于实现的,但通常应用程序已经启动并且它的 main 方法已经被调用。如果实现支持在 VM 启动后启动代理,则适用以下情况:
1.agent JAR的manifest必须包含属性Agent-Class。该属性的值是代理类的名称。
2.代理类必须实现一个公共静态agentmain方法。
3. 系统类加载器(ClassLoader.getSystemClassLoader)必须支持将代理JAR 文件添加到系统类路径的机制。
但我从未尝试过:-|
这里是一个通过注入检测在运行时初始化 aspectj 和 spring-aspects 的库:https ://github.com/subes/invesdwin-instrument
您可以将其用作更精细的示例。