-
Notifications
You must be signed in to change notification settings - Fork 8
Java Agent
Java从1.5提供了java.lang.instrument包,用于给JVM植入java编程语言编写的Instrumentation,这种通过java.lang.instrument实现工具被称为java agent。java agent可以在JVM加载class时候修改目标字节码,或者修改已经加载的class的信息(已经加载的class不会再次初始化,可以调整方法体,但是不能添加/删除/重命名字段或方法,不能修改方法的签名或者更改继承)。
目前java agent支持两种模式加载,启动时加载,通过在JVM启动时配置-javaagent:jarpath[=options],还有一种通过Attach API动态加载java agent。
目前基于java agent实现应用的工具有很多,例如SkyWalking(APM),Arthas(诊断),ChaosBlade(混沌注入),JaCoCo(代码覆盖率)等等。
JVM命令行启动配置模式:
首先命令行需要增加-javaagent:jarpath[=options]参数,jarpath为java agent Jar包的路径,agent Jar中的manifest文件必须包含Premain-Class属性,属性值为agent class,该类必须包含premain方法,premain方法可以有两种形式:
public static void premain(String agentArgs, Instrumentation inst); (两个方法同时出现时,该方法优先级较高)
public static void premain(String agentArgs);java agent由system class loader负责加载(ClassLoader.getSystemClassLoader),所以在premain阶段,很多时候是看不到当前目标程序引用的资源的。通过agentArgs可以获取到Agent配置的options,具体参数的解析需要由Agent自身解析。
JVM启动后Attach模式:
在目标JVM启动后attach上去,agent Jar中的manifest文件必须包含Agent-Class属性,属性值为agent class,该类必须包含agentmain方法,agentmain方法可以有两种形式:
public static void agentmain(String agentArgs, Instrumentation inst);(两个方法同时出现时,该方法优先级较高)
public static void agentmain(String agentArgs);attach模式java agent也是由system class loader负责加载(ClassLoader.getSystemClassLoader)。