@Override
public byte[] transform(ClassLoader loader, ..)
throws .. {
byte[] byteCode = classfileBuffer;
// If you wanted to intercept all the classs then you can remove this conditional check.
if (className.equals("Example")) {
try {
ClassPool classPool = scopedClassPoolFactory.create(loader, rootPool,
ScopedClassPoolRepositoryImpl.getInstance());
CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtMethod[] methods = ctClass.getDeclaredMethods();
for (CtMethod method : methods) {
if (method.equals("main")) {
method.insertAfter("System.out.println(\"Logging using Agent\");");
byteCode = ctClass.toBytecode();
ctClass.detach();
} catch (Throwable ex) {
log.log(Level.SEVERE, "Error in transforming the class: " + className, ex);
return byteCode;
ctClass.detach();
} catch (Throwable ex) {
log.log(Level.SEVERE, "Error in transforming the class: " + className, ex);
return byteCode;
在这里,从类池中,我们可以直接绕过classfileBuffer
获取类,因为我想使用main
方法。我们循环遍历类定义中的所有方法,得到我们想要的类。我们根本不需要使用字节码。我们可以简单地向它传递一些合法的Java代码,然后Javassist将编译它,生成新的字节码,并给出定义。
有三种方法可以向方法中插入一些Java代码。insertAfter(..)
在正文末尾插入字节码。它在正文的末尾插入字节码。insertAt(..)
在正文的指定行插入字节码,insertBefore(..)
在正文的开头插入字节码。
使用Java代理进行实际操作
从指定的链接下载示例应用程序和Java Agent。
使用进入路径并执行命令mvn clean install
来构建这两个repo
现在,您将获得目标中的jar文件。复制示例应用程序中.jar文件的路径,并复制Java Agent中-dependencies.jar
文件的路径。
首先,使用命令$java-jar<path of the packaged jar>
仅与示例应用程序一起运行应用程序,并观察输出。Hi I am main
。将在控制台中打印。
然后,使用命令$ java -javaagent:<path of agent jar file> -jar <path of the packaged jar
file you want to intercept>
并观察输出。将在控制台中另外打印使用代理的日志记录。这确保java agent被拦截并添加到main
方法的主体中。
总之,如果要实现Java Agent,请执行以下操作:
1. 您需要创建两个Java类。一个是premain
方法(JavaAgent),另一个是扩展ClassFileTransformer
的类(CustomTransformer
)
2. 在premain
方法的主体内,需要添加扩展ClassFileTransformer
的类的对象
3. 然后,您需要在CustomTransformer
中的重写方法transform
中添加逻辑。
4. 在转换方法内转换字节码时,可能需要根据用途使用字节码生成库。
5. 您需要在清单中指定premain
类并构建jar。
6. 使用javaagent
标记将代理加载到要拦截的应用程序中。
在这篇文章中,我们看到了Java开发者工具带中一个非常强大的条目:Java agent。它有权访问加载到JVM中的类。你可能会想,我们做了太多的工作却收效甚微。答案是肯定的“否”。首先,您必须记住,Hello world示例在这里详细说明了Java agent的使用。使用java agent可以做的事情是巨大的,当需要重写复杂的代码时,这些事情非常方便。我只是初步了解了使用java agent可以实现的功能,但希望在阅读本文之后,您现在能够了解它们的存在,并可以进一步研究。然而,为了持久性和适当的监控,构建一个可靠的java agent是一项需要由专门的工程师团队来完成的任务。让我知道你进展如何!
原文地址:https://dzone.com/articles/java-agent-1
无代码侵入的数据采集和Mock,支持Spring、Dubbo、Redis、Mybatis等开源框架的录制和回放;
支持各种复杂业务场景的验证:多线程并发、异步回调、写操作等;
欢迎扫码进QQ群交流
官网:http://arextest.com
github:https://github.com/arextest