Java Agent入门教程

发布时间 2023-06-12 14:43:46作者: 扰扰

一、核心逻辑

创建一个新的项目(or 子 module),然后我们新建一个 SimpleAgent 类:

package com.raorao.text;

import java.lang.instrument.Instrumentation;

/**
 * @Description : 启动类
 * @Author : cxw
 * @Date : 2023/6/12 14:18
 * @Version : 1.0
 **/
public class MySimpleAgent {
    /**
     * jvm 参数形式启动,运行此方法
     *
     * @param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("premain agentArgs="+agentArgs);
    }

    /**
     * 动态 attach 方式启动,运行此方法
     *
     * @param agentArgs
     * @param inst
     */
    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("agentmain agentArgs="+agentArgs);
    }
}

先简单看一下这两个方法的区别,注释上也说了

jvm 参数形式: 调用 premain 方法
attach 方式: 调用 agentmain 方法

其中 jvm 方式,也就是说要使用这个 agent 的目标应用,在启动的时候,需要指定 jvm 参数 -javaagent:xxx.jar。然后执行 main 函数之前,JVM 会先运行 -javaagent 所指定 jar 包内 Premain-Class 这个类的 premain 方法,即在主程序运行之前先启动运行agent。
当目标应用程序启动之后,动态attach的方式启动agent,这时候就可以使用 attach 方式来使用。

二、打包

上面一个简单 SimpleAgent 就把我们的 Agent 的核心功能写完了(就是这么简单),接下来需要打一个 Jar 包。通过 maven 插件,可以比较简单的输出一个合规的 java agent 包,有两种常见的使用姿势:

2.1. pom 指定配置方式
在 pom.xml 文件中,添加如下配置,请注意一下manifestEntries标签内的参数

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
<!--                <version>1.3</version>-->
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifestEntries>
                            <Premain-Class>com.raorao.text.MySimpleAgent</Premain-Class>
                            <Agent-Class>com.raorao.text.MySimpleAgent</Agent-Class>
                            <Can-Redefine-Classes>true</Can-Redefine-Classes>
                            <Can-Retransform-Classes>true</Can-Retransform-Classes>
                        </manifestEntries>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>attached</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

然后通过 mvn assembly:assembly 命令打包,在target目录下,可以看到一个后缀为jar-with-dependencies的 jar 包,就是我们的目标:

2.2. MANIFEST.MF 配置文件方式
通过配置文件MANIFEST.MF,可能更加常见,这里也简单介绍下使用姿势

-在资源目录(Resources)下,新建目录META-INF
-在META-INF目录下,新建文件MANIFEST.MF

文件内容如下:

 请注意,最后一行要有一个空行,不能少,在 idea 中,删除最后一行时,会有错误提醒:

 然后我们的pom.xml配置,需要作出对应的修改:

 同样通过mvn assembly:assembly命令打包

三、Agent使用

agent 有了,接下来就是需要测试一下使用 agent 的使用了,上面提出了两种方式,下面分别进行说明:
jvm 参数 请注意VM options的内容为之前打包的 agent 绝对地址:

-javaagent:D:\web\agenttest\target\agen-test-1.0-SNAPSHOT-jar-with-dependencies.jar

首先新建一个 demo 项目,写一个简单的测试类:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(6条消息) Java Agent入门教程_程序员杨叔的博客-CSDN博客