Java Agent(一)

本文介绍了Java Agent技术,包括预主方法(premain)和代理方法(agentmain),以及如何通过MANIFEST.MF文件配置。通过Java Agent,可以在程序运行前或运行后改变行为,实现AOP功能,例如JRebel和BTrace。文章还展示了如何使用attach机制动态加载agent,以及Java Instrumentation API在字节码级别的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        热部署插件通过agent来实现的,在JDK1.5以后,我们可以使用agent技术构建一个独立于应用程序的代理程序(即为Agent),用来协助监测、运行甚至替换其他JVM上的程序。使用它可以实现虚拟机级别的AOP功能。(JrebelBTrace

首先要有一个agent程序,一个类。

有一个premain方法,顾名思义它代表着他将在主程序的main方法之前运行,agentArgs代表传递过来的参数,inst则是agent技术主要使用的API,我们可以使用它来改变和重新定义类的行为。

2、编写MANIFEST.MF文件

        MANIFEST.MF文件用于描述Jar包的信息,例如指定入口函数等。我们需要在该文件中加入如下配置,指定我们编写的含有premain方法类的全路径,然后将agent类打成Jar包。如果你是使用Maven来构建的项目,在构建的时候加入如下代码,否则Maven会生成自己的MANIFEST.MF覆盖掉你的。

 3、编写主程序

主程序的VM options添加上启动参数

-javaagent: 你的路径/test-1.0-SNAPSHOT.jar=hah

其中hah为上文中传入permain方法的agentArgs参数。运行我们的主程序

在主程序运行之前的agent模式有一些缺陷,例如需要在主程序运行前就指定javaagent参数,premain方法中代码出现异常会导致主程序启动失败等,为了解决这些问题,JDK1.6以后提供了在程序运行之后改变程序的能力。它的实现步骤和之前的模式类似。

我们复用上面的类,将premain方法修改为agentmain方法,由于是在主程序运行后再执行,意味着我们可以获取主程序运行时的信息,这里我们打印出来主程序中加载的类名。

重复上面第二步骤,修改MANIFEST.MF文件。

添加Agent-Class参数,打成Jar包。

3、启动主程序,编写加载agent类的程序

在程序运行后加载,我们不可能在主程序中编写加载的代码,只能另写程序,那么另写程序如何与主程序进行通信?这里用到的机制就是attach机制,它可以将JVM A连接至JVM B,并发送指令给JVM B执行,JDK自带常用工具如jstack,jps等就是使用该机制来实现的。这里我们先用tomcat启动一个程序用作主程序B,再来写A程序代码。

我们使用VirtualMachine attach到目标进程,其中78256为tomcat进程的PID,可以使用jps命令获得,也可以使用VirtualMachine.list方法获取本机上所有的Java进程,再来判断tomcat进程,loadAgent方法第一个参数为Jar包在本机中的路径,第二个参数为传入agentmain的args参数,此处为null,运行程序。

我们是将进程attach到了tomcat进程上,agent其实是在主程序B中运行的,所以程序A中自然就不会进行打印,我们跳回tomcat程序的控制台,查看结果。

以上就是Java Agent的俩个简单小栗子了,Java Agent十分强大,它能做到的不仅仅是打印几个监控数值而已,还包括使用Transformer(推荐观看等高级功能进行类替换,方法修改等,要使用Instrumentation的相关API则需要对字节码等技术有较深的认识。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值