JVM的动态agent机制:在main函数启动以后运行agent

premain是Java SE5开始就提供的代理方式,因为其必须在命令行指定代理jar,而且代理类必须在main方法前启动。所以,要求开发者在应用前就必须确认代理的处理逻辑和参数内容等等。在有些场合下,premain代理方式不能知足需求。为解决运行时启动代理类的问题,Java SE6开始提供了在应用程序的VM启动后在动态添加代理的方式,即agentmain方式。 java

与Permain相似,agent方式一样须要提供一个agent jar,而且这个jar须要知足:
一、在manifest中指定Agent-Class属性,值为代理类全路径
二、代理类须要提供public static void agentmain(String args, Instrumentation inst)或public static void agentmain(String   args)方法。而且再两者同时存在时之前者优先。args和inst和premain中的一致
 api

package aty.agent.after;
 
import java.lang.instrument.Instrumentation;
 
public class AgentAfterMain
{
	public static void agentmain(String args, Instrumentation inst)
	{
		System.out.println("loadagent after main run.args=" + args);
 
		Class<?>[] classes = inst.getAllLoadedClasses();
 
		for (Class<?> cls : classes)
		{
			System.out.println(cls.getName());
		}
 
		System.out.println("agent run completely.");
	}
}

将该代理类打成jar包,并修改MANIFEST.MF文件
Manifest-Version: 1.0
Agent-Class: aty.agent.after.AgentAfterMain
jvm

编写好agent jar以后,接下来须要将该jar挂接到目标进程的jvm中执行。因为agent main方式没法向pre main方式那样在命令行指定代理jar,所以须要借助Attach Tools API。使用com.sun.tools.attach包下的VirtualMachine类,使用attach pid 来获得相应的VirtumalMachine,使用loadAgent 方法指定AgentMain所在类并加载。其中com.sun.tools.attach.VirtualMachine的jar包是jdk下lib中的tools.jar
 spa

package aty.agent.after;
 
import com.sun.tools.attach.VirtualMachine;
 
public class RunAttach
{
 
	public static void main(String[] args) throws Exception
	{
		// args[0]传入的是某个jvm进程的pid
		String targetPid = args[0];
 
		VirtualMachine vm = VirtualMachine.attach(targetPid);
 
		vm.loadAgent("F:/workspaces/j2se练习代码/jvm_high_api/agentmain.jar",
				"toagent");
	}
}
相关文章
相关标签/搜索