赞
踩
目录
java agent本质上可以理解为一个插件,该插件就是一个精心提供的jar包,这个jar包通过JVMTI(JVM Tool Interface)完成加载,最终借助JPLISAgent(Java Programming Language Instrumentation Services Agent)完成对目标代码的修改。
java agent技术的主要功能如下:
可以在加载java文件之前做拦截把字节码做修改
可以在运行期将已经加载的类的字节码做变更
还有其他的一些小众的功能
Java Agent的原理主要是通过Java的Instrumentation API和JVMTI(Java Virtual Machine Tool Interface)来实现的。
Java Agent是一种运行在JVM中的特殊程序,可以在运行时修改或分析类的字节码。通过Instrumentation API,Java Agent可以在类加载到JVM之前或之后,对类的字节码进行修改或分析,以实现各种功能,如性能监控、故障排查、代码热替换等。
JVMTI是JVM提供的一组原生接口,用于监控和控制JVM的运行状态。Java Agent可以通过JVMTI获取JVM的运行信息,如线程状态、内存使用情况等,以实现更加精细的控制和监控。
总的来说,Java Agent的原理是通过Instrumentation API和JVMTI,在运行时对类的字节码进行修改或分析,以实现各种功能。
通过java agent技术进行类的字节码修改最主要使用的就是Java Instrumentation API。下面将介绍如何使用Java Instrumentation API进行字节码修改。
Java Agent支持目标JVM启动时加载,也支持在目标JVM运行时加载,这两种不同的加载模式会使用不同的入口函数,如果需要在目标JVM启动的同时加载Agent,那么可以选择实现下面的方法:
[1] public static void premain(String agentArgs, Instrumentation inst);
[2] public static void premain(String agentArgs);
JVM将首先寻找[1],如果没有发现[1],再寻找[2]。如果希望在目标JVM运行时加载Agent,则需要实现下面的方法:
[1] public static void agentmain(String agentArgs, Instrumentation inst);
[2] public static void agentmain(String agentArgs);
这两组方法的第一个参数AgentArgs是随同 “–javaagent”一起传入的程序参数,如果这个字符串代表了多个参数,就需要自己解析这些参数。inst是Instrumentation类型的对象,是JVM自动传入的,我们可以拿这个参数进行类增强等操作。
启动时加载
启动参数增加-javaagent:[path],其中path为对应的agent的jar包路径
运行中加载
使用com.sun.tools.attach.VirtualMachine加载
启动时修改主要是在jvm启动时,执行native函数的Agent_OnLoad方法,在方法执行时,执行如下步骤:
创建InstrumentationImpl对象
监听ClassFileLoadHook事件
调用InstrumentationImpl的loadClassAndCallPremain方法,在这个方法里会去调用javaagent里MANIFEST.MF里指定的Premain-Class类的premain方法
运行时修改主要是通过jvm的attach机制来请求目标jvm加载对应的agent,执行native函数的Agent_OnAttach方法,在方法执行时,执行如下步骤:
创建InstrumentationImpl对象
监听ClassFileLoadHook事件
调用InstrumentationImpl的loadClassAndCallAgentmain方法,在这个方法里会去调用javaagent里MANIFEST.MF里指定的Agentmain-Class类的agentmain方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。