创建一个 java agent jar 包
- pom.xml 文件。(javaagent 和 main 方法的 jar 可以分开成两个项目,单独打包 jar)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>app</artifactId>
<packaging>jar</packaging>
<version>0.1</version>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>org.example.MainApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifestEntries>
<Premain-Class>org.example.MyAgent</Premain-Class>
<Agent-Class>org.example.MyAgent</Agent-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 创建 premain 方法,方法的主要功能是修改 App setName() 方法体
public class MyAgent {
public static void premain(String args, Instrumentation inst) {
MyTransformer tran = new MyTransformer();
inst.addTransformer(tran);
}
}
public class MyTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if ("org/example/App".equals(className)) {
try {
// 从ClassPool获得CtClass对象
final ClassPool classPool = ClassPool.getDefault();
final CtClass clazz;
clazz = classPool.get("org.example.App");
CtMethod convertToAbbr = clazz.getDeclaredMethod("setName");
String methodBody = "{\n" +
" this.name = \"ccc\" + \" aaa\";\n" +
" }";
convertToAbbr.setBody(methodBody);
byte[] byteCode = clazz.toBytecode();
clazz.detach();
return byteCode;
} catch (NotFoundException | CannotCompileException | IOException e) {
e.printStackTrace();
}
}
System.out.println(className);
return classfileBuffer;
}
}
public class App {
private int code;
private String name;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "App{" +
"code=" + code +
", name='" + name + '\'' +
'}';
}
}
public class MainApp {
public static void main(String... args) throws Exception {
App app = new App();
app.setName("a");
app.setCode(123);
System.out.println(app);
}
}
- 启动 javaagent
java -javaagent:app-0.1-jar-with-dependencies.jar -jar app-0.1.jar
控制台输出
App{code=123, name='ccc aaa'}
name 属性被成功修改
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
2022-11-08 Windows 端口转发工具
2022-11-08 leetcode-819-easy
2022-11-08 leetcode-2176-easy
2022-11-08 leetcode-520-easy
2022-11-08 leetcode-1784-easy
2022-11-08 leetcode-561-easy
2022-11-08 leetcode-1854-easy