JAVA AgentMain开发示例

18 篇文章 1 订阅

agentmain方式

        premain是Java SE5开始就提供的代理方式,给了开发者诸多惊喜,不过也有些须不便,由于其必须在命令行指定代理jar,并且代理类必须在main方法前启动。因此,要求开发者在应用前就必须确认代理的处理逻辑和参数内容等等,在有些场合下,这是比较困难的。比如正常的生产环境下,一般不会开启代理功能,但是在发生问题时,我们不希望停止应用就能够动态的去修改一些类的行为,以帮助排查问题,这在应用启动前是无法确定的。 为解决运行时启动代理类的问题,Java SE6开始,提供了在应用程序的VM启动后在动态添加代理的方式,即agentmain方式。 与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中的一致。

        不过如此设计的在运行时进行代理有个问题——如何在应用程序启动之后再开启代理程序呢? JDK6中提供了Java Tools API,其中Attach API可以满足这个需求。

        Attach API中的VirtualMachine代表一个运行中的VM。其提供了loadAgent()方法,可以在运行时动态加载一个代理jar。
agentmain实例-打印当前已加载的类

构造agent类

agentmain方式的代理类必须提供agentmain方法:

package loaded;
import java.lang.instrument.Instrumentation;
public class LoadedAgent { 
    public static void agentmain(String args, Instrumentation inst){
        Class[] classes = inst.getAllLoadedClasses();
        for(Class cls :classes){
            System.out.println(cls.getName());
        }
    }
}

agentmain方法通过传入的Instrumentation实例获取当前系统中已加载的类。

设置MANNIFEST.MF

        设置MANIFEST.MF文件,指定Agent-Class:

Manifest-Version: 1.0
Agent-Class: loaded.LoadedAgent
Created-By: 1.6.0_29

绑定到目标VM

将agent类和MANIFEST.MF文件编译打包成loadagent.jar后,由于agent main方式无法向premain方式那样在命令行指定代理jar,因此需要借助Attach Tools API。

使用com.sun.tools.attach 的VirtualMachine类
使用attach pid 来得到相应的 VirtumalMachine,
使用loadAgent 方法指定AgentMain所在类并加载

注意 com.sun.tools.attach.VirtualMachine的jar包是jdk下lib中的tools.jar

package attach;
import java.io.IOException;
import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;

public class AttachTest {
    public static void main(String[] args) throws AttachNotSupportedException,
            IOException, AgentLoadException, AgentInitializationException {
        VirtualMachine vm = VirtualMachine.attach(args[0]);//args[0]传入的是jvm的pid号
     //   vm.loadAgent("/Users/jiangbo/Workspace/code/java/javaagent/loadagent.jar");
         vm.loadAgent("F:\\workspace_aging_rejuvenate\\AgentMain\\agent.jar");

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值