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");
	}
}
相關文章
相關標籤/搜索