JavaAgent插桩技术介绍

Java 代理(agent)是一种拦截处理技术,它会在你的 Java 代码执行前进行拦截并按照你的要求进行字节码调整。

我们开发中使用的很多工具都是基于 Java 代理来实现的,比如 JRebel、以及诊断工具等。

Java Agent规范

因为其特殊性,Java Agent 规定,需要在 META-INF 目录下创建 MANIFEST.MF 文件,并在其内部指定 Agent 的启动类:

Manifest-Version: 1.0
Premain-Class: org.example.App
Archiver-Version: Plexus Archiver
Built-By: jack
Agent-Class: org.example.App
Created-By: Apache Maven 3.2.5
Build-Jdk: 1.8.0_40

上述仅为示例文件,具体配置请根据实际情况处理

Java Agent 入口类

上述配置中设置了Premain-ClassAgent-Class的类路径,这代表着我们的 Agent 在不同的运行方式下会找不同的入口类。

Premain-Class代表的是以-javaagent:*的方式载入时,Agent 程序的入口类路径。

-javaagent:/jetbrains-all/current/ja-netfilter.jar=jetbrains

Agent-Class则代表的是以 Attach API 的方式载入时,Agent 程序的入口类路径。

public class Attacher {
    public static void main(String[] args) throws AttachNotSupportedException, IOException, AgentLoadException, AgentInitializationException {
        // 传入目标 JVM pid
        VirtualMachine vm = VirtualMachine.attach("39333");
        vm.loadAgent("/jetbrains-all/current/ja-netfilter.jar");
    }
}

入口类的定义如下:

public class App {
    /**
     * 以vm参数的方式载入,在Java程序的main方法执行之前执行
     */
    public static void premain(String agentArgs, Instrumentation inst) {}
    /**
     * 以Attach的方式载入,在Java程序启动后执行
     */
    public static void agentmain(String agentArgs, Instrumentation inst) {}
}

Maven Build

为了便于打包,一般我们会使用 Maven 的 Plugin 进行自动配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <archive>
            <!--自动添加META-INF/MANIFEST.MF -->
            <manifest>
                <addClasspath>true</addClasspath>
            </manifest>
            <manifestEntries>
                <Premain-Class>com.rickiyang.learn.PreMainTraceAgent</Premain-Class>
                <Agent-Class>com.rickiyang.learn.PreMainTraceAgent</Agent-Class>
                <Can-Redefine-Classes>true</Can-Redefine-Classes>
                <Can-Retransform-Classes>true</Can-Retransform-Classes>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

使用场景

Java Agent 结合 ASM 技术可以做到很多事情,主要包含以下几种场景:

  1. 日志记录
  2. 性能分析
  3. 热部署
  4. Mock服务
  5. 动态数据映射
  6. ……

JavaAgent插桩技术介绍
https://blog.cikaros.top/doc/492edb0a.html
作者
Cikaros
发布于
2024年7月2日
许可协议