什么是Java Agent
Java Agent是一种特别的Java 类,能通过Java Instrumentation API实现对JVM的应用类进行拦截,并修改字节码。
Java Agent的premain方法
当JVM初始化后,首先调用Java Agent类的premain方法,接着调用main方法。
织入Java Agent类的两种场景
- 静态agent
当我们需要把要织入的Java Agent类,随着被织入的应用类JVM一起启动时,则使用静态agent。
实现方法:
public class JavaAgent {
/**
* As soon as the JVM initializes, This method will be called.
*
* @param agentArgs The list of agent arguments
* @param instrumentation The instrumentation object
* @throws InstantiationException
*/
public static void premain(String agentArgs, Instrumentation instrumentation) throws InstantiationException {
InterceptingClassTransformer interceptingClassTransformer = new InterceptingClassTransformer();
interceptingClassTransformer.init();
instrumentation.addTransformer(interceptingClassTransformer);
}
}
- Java Agent类样例如上图。
- 把Java Agent类打包成一个jar文件,并在src/main/resources/META-INF/MANIFEST.MF文件中定义Premain-Class: org.example.JavaAgent。
- 启动命令,添加-javaagent参数,如下:
java -javaagent:<path of agent jar file> -jar <path of the packaged jar file you want to intecept>
- 动态agent
当我们需要把Java Agent类,织入至已处于运行状态应用类JVM时,则使用动态agent。样例代码如下:
VirtualMachine vm = VirtualMachine.attach(vmPid);
vm.load(agentFilePath);
vm.detach();
ClassFileTransformer接口
ClassFileTransformer接口在java.lang.instrumentation包中, 主要作用是通过其transform方法修改载入JVM的字节码数据。
编写一个使用Java Agent 的demo
https://github.com/XiamenGeek/skywalking-agent-demo
https://github.com/XiamenGeek/SkywalkingTest
参考来源:
《Apache Skywalking 实战》