前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java Agent 开发初探

Java Agent 开发初探

作者头像
FunTester
发布于 2025-01-23 07:53:27
发布于 2025-01-23 07:53:27
10100
代码可运行
举报
文章被收录于专栏:FunTesterFunTester
运行总次数:0
代码可运行

Java Agent 概况

简介和功能

Java Agent是一种特殊的Java程序,允许开发者在 Java 应用程序运行时对其进行动态修改和监控的机制。它利用了 Java 虚拟机(JVM)的 java.lang.instrument 包提供的功能,可以在类加载时或运行时对字节码进行修改。这种技术通常用于性能监控、安全检测、调试和诊断等场景。

Java Agent 主要功能如下:

  • 字节码增强:在类加载时或运行时动态修改类的字节码,以添加新的功能或改变现有行为。
  • 性能监控:收集应用程序运行时的性能数据,如方法调用频率、执行时间等。
  • 安全检查:在类加载时对类进行安全检查,确保其符合特定的安全策略。
  • 调试和诊断:在不修改应用程序源代码的情况下,插入调试和诊断代码,以帮助开发和排查问题。

应用场景

Java Agent的应用场景非常广泛,以下是一些常见的使用案例:

  • 性能监控:通过插入监控代码来收集应用程序的性能数据,例如方法调用时间、内存使用情况等。
  • 安全性检查:在运行时动态地检查和加固应用程序,防止安全漏洞。
  • 调试与诊断:在不修改源代码的情况下,为应用程序添加日志输出或调试信息。
  • 动态AOP(面向切面编程):实现在运行时动态地插入切面逻辑,而无需在编译时进行代码修改。

那么,我们如何开发一个 Java Agent 呢,下面我们来仔细说说。

开发 Java Agent

Java Agent 通过实现 java.lang.instrument.ClassFileTransformer 接口,并将其注册到 Instrumentation 对象中,可以在类加载时对类的字节码进行修改。Instrumentation 对象是在 JVM 启动时由 Java Agent 提供的,可以通过 premain 方法获取。开发 Java Agent 需要遵循一下规范,下面是几个必备的部分:

实现 premain 方法

premain 方法是 Java Agent 的入口点,类似于主程序的 main 方法。它在 JVM 启动时被调用,并传递 Instrumentation 对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 import java.lang.instrument.Instrumentation;

 public class MyAgent {
  public static void premain(String agentArgs, Instrumentation inst) {
// 注册 ClassFileTransformer
inst.addTransformer(new MyClassFileTransformer());
  }
 }

实现 ClassFileTransformer 接口

ClassFileTransformer 接口的 transform 方法在每个类加载时被调用,可以在这里对类的字节码进行修改。我们也可以创建一个 Java Agent 而不实现 ClassFileTransformer 接口,而是只实现两个方法:premain 和(可选的)agentmain。这样,你仍然可以使用 Java Agent 的一些基本功能,例如在 JVM 启动时执行某些初始化代码或在运行时加载 Agent

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.IllegalClassFormatException;
 import java.security.ProtectionDomain;

 public class MyClassFileTransformer implements ClassFileTransformer {
  @Override
  public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
  ProtectionDomain protectionDomain, byte[] classfileBuffer)
  throws IllegalClassFormatException {
// 这里可以对 classfileBuffer 进行修改
System.out.println("Loading class: " + className);
return classfileBuffer;
  }
 }

打包 Java Agent

Java Agent 要求 JAR 包的 MANIFEST.MF 文件中要有 Premain-Class 属性,不切指定 Agent 类。通常我们使用 Maven 打包工具来完成,下面是个例子(篇幅限制,只展示了 build 不分):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Premain-Class>com.example.MyAgent</Premain-Class>
                            <Agent-Class>com.example.MyAgent</Agent-Class>
                            <Can-Redefine-Classes>true</Can-Redefine-Classes>
                            <Can-Retransform-Classes>true</Can-Retransform-Classes>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

使用 Java Agent

使用 -javaagent 参数来加载 Java Agent。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 java -javaagent:MyAgent.jar -jar YourApp.jar

还有一种动态加载的方式,使用 attack API 来完成。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String pid = ...; // 获取目标JVM的进程ID
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgent("/path/to/MyAgent.jar");
vm.detach();

代码解释:

  1. 获取目标 JVM 的进程 ID:首先,需要获取目标 JVM 进程的 PID(进程 ID)。可以通过 JMX、jps 命令或其他方法获取。
  2. 附加到目标 JVM:使用 VirtualMachine.attach(pid) 方法附加到目标 JVM 进程。这个方法返回一个 VirtualMachine 对象,该对象代表目标 JVM。
  3. 加载 Java Agent:使用 VirtualMachine 对象的 loadAgent 方法加载 Java Agent。传递 Java Agent JAR 文件的路径,这会在目标 JVM 中执行该 Agent。
  4. 分离:加载完 Agent 后,通过 VirtualMachine 对象的 detach 方法分离当前 JVM 与目标 JVM 的连接,确保操作完成并释放资源。

实用案例

性能监控

Java Agent技术在性能监控领域的应用非常广泛,它可以帮助开发者实时监控应用程序的运行状态,识别性能瓶颈。

  • 实时监控:通过Java Agent,可以在应用程序运行时动态地收集CPU、内存、线程等关键性能指标的数据。
  • 数据收集:Agent可以在不干扰应用程序正常运行的情况下,收集方法调用、执行时间等信息,为性能分析提供数据支持。
  • 性能分析工具集成:Java Agent可以与现有的性能分析工具如VisualVM、JProfiler等集成,实现数据的自动收集和分析。
  • 自定义监控逻辑:开发者可以根据需要编写自定义的监控逻辑,例如监控特定方法的调用频率、执行时间等,并通过Agent在运行时动态地插入到应用程序中。

安全性检查

  • Java Agent也常用于安全性检查,帮助发现和预防潜在的安全漏洞。
  • 代码注入:Agent可以在类加载时动态地注入安全检查代码,例如检查SQL查询语句,防止SQL注入攻击
  • 运行时检查:在应用程序运行时,Agent可以实时监控系统调用,检测潜在的安全威胁,如未授权的文件访问尝试。
  • 安全策略实施:通过Agent,可以实施自定义的安全策略,如限制特定方法的调用权限,增强应用程序的安全性。
  • 漏洞扫描:Agent可以集成漏洞扫描工具,对应用程序进行深度的安全检查,及时发现并修复安全漏洞。

性能影响

开发Java Agent时,性能影响是一个需要特别关注的问题。由于Agent会在目标应用程序的JVM中运行,其字节码转换和监控操作可能会对应用程序的性能产生一定的影响。

  • 字节码转换开销:在类加载时进行字节码转换会增加类加载的时间,尤其是在启动阶段,可能会延长应用程序的启动时间。
  • 运行时监控:Agent进行的实时监控和数据收集可能会占用额外的CPU和内存资源,影响应用程序的响应时间和吞吐量。
  • 调试难度:由于Agent的介入,应用程序的行为可能会发生变化,这使得调试和定位问题变得更加复杂。

为了最小化性能影响,开发者应该:

  • 优化字节码转换逻辑:尽量简化转换逻辑,减少不必要的操作,提高转换效率。
  • 合理配置监控频率:根据实际需求合理设置监控数据的采集频率,避免过度监控。
  • 进行性能测试:在部署Agent之前,进行充分的性能测试,评估其对应用程序性能的影响,并根据测试结果进行优化。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java Agent(一)、初步认识Instrumentation
Instrumentation 是 Java SE 5 引入的一套 API,它允许开发者在运行时修改类的字节码。Java Instrumentation 可以实现在方法插入额外的字节码从而达到收集使用中的数据到指定工具的目的。Java.lang.instrument包的最大功能就是可以在已有的类上附加(修改)字节码来实现增强的逻辑,它最常见的用途包括:
有一只柴犬
2024/12/10
2210
Java Agent(一)、初步认识Instrumentation
99%的Java程序员不知道的Java Instrument-IDEA 破解的原理
Java Instrumentation API 是一个强大的工具,它允许开发人员在运行时修改字节码,而无需重新编译或修改源代码。这对于性能监控、日志记录、安全审计等场景非常有用。本文将深入探讨Java Instrumentation的基础知识,并通过具体的代码示例来展示如何使用-javaagent选项以及premain和agentmain方法来实现一些实用的功能。
井九
2024/10/12
1110
99%的Java程序员不知道的Java Instrument-IDEA 破解的原理
JVM 字节码增强技术之 Java Agent 入门
分布式链路追踪中为了获取服务之间调用链信息,采集器通常需要在方法的前后做埋点。在 Java 生态中,常见的埋点方式有两种:
高楼Zee
2021/10/27
1.5K0
谈谈Java Agent技术的实现
Java Agent本质上可以理解为一个插件,该插件就是一个精心提供的Jar包,这个Jar包通过JVMTI(JVM Tool Interface)完成加载,最终借助JPLISAgent(Java Programming Language Instrumentation Services Agent)完成对目标代码的修改。
FB客服
2022/11/14
3930
谈谈Java Agent技术的实现
浅谈 Java Agent 内存马
https://www.yuque.com/tianxiadamutou/zcfd4v/tdvszq
亿人安全
2022/06/30
2.5K0
浅谈 Java Agent 内存马
Java代理技术解密:揭秘方法计时器的神奇实现
最近在了不起在与外部交流的时候,Java的agent技术被提起,想来自己都有些时间没有使用它了,本文简单讲讲什么是agent技术,并结合一个方法计时器的实际例子。
灬沙师弟
2023/07/08
1920
Java代理技术解密:揭秘方法计时器的神奇实现
​Java Agent原理及实现
Java Agent是Java SE 5.0版本引入的一个新特性,它可以在Java虚拟机(JVM)启动前或者在运行时动态地读取一些class文件,并在内存中修改后替换原始的class文件,从而在不改变原有代码的情况下增强或者监视应用程序的运行。
架构狂人
2023/08/16
9260
​Java Agent原理及实现
认识 JavaAgent --获取目标进程已加载的所有类
之前在一个应用中搜索到一个类,但是在反序列化测试时出错,错误不是class notfound,是其他0xxx这样的错误,通过搜索,这个错误大概是类没有被加载。最近刚好看到了JavaAgent,初步学习了下,能进行拦截,主要通过Instrument Agent来进行字节码增强,可以进行字节码插桩,bTrace,Arthas 等操作,结合ASM,javassist,cglib框架能实现更强大的功能。Java RASP也是基于JavaAgent实现的。趁热记录下JavaAgent基础概念,以及简单使用JavaAgent实现一个获取目标进程已加载的类的测试。
Seebug漏洞平台
2019/12/16
2.2K0
认识 JavaAgent --获取目标进程已加载的所有类
【Java编程进阶之路 04】深入探索:Java类加载器与双亲委派 & 打破双亲委派桎梏
在Java的世界里,类加载器(ClassLoader)是一个核心组件,它负责在运行时动态加载Java类到JVM中。为了确保Java应用的安全和稳定,Java设计者们引入了一种称为“双亲委派模型”(Parent Delegation Model)的类加载机制。这种机制不仅避免了类的重复加载,还保护了系统的安全。下面我们将详细探讨双亲委派机制的工作原理、优势、以及它在Java生态系统中的应用。
夏之以寒
2024/03/05
2170
深入理解Instrument(一)
很早之前就了解到目前主流的APM开源框架如Pinpoint、SkyWalking等等都是通过java.lang.instrument包提供的字节码增强功能来实现的。趁着对这块的热情还没消退,抽时间分析一下java.lang.instrument包的使用方式,记录下来写成一个系列的文章。本系列博文针对的是JDK11,其他版本的JDK可能不适合。
Throwable
2020/06/23
3K0
深入理解Instrument(一)
动态追踪之java agent
上篇文章我们说到阿里的诊断工具Arthas对方法和类的监控使用的是动态追踪技术,本文我们将介绍动态追踪技术Java Agent。
索码理
2022/12/28
9080
动态追踪之java agent
字节码调试的入口 —— JVM 的寄生插件 javaagent 那些事
Java Instrumentation 这个技术看起来非常神秘,很少有书会详细介绍。但是有很多工具是基于 Instrumentation 来实现的:
架构狂人
2023/08/16
1K0
字节码调试的入口 —— JVM 的寄生插件 javaagent 那些事
使用代理(Agent)的Java Bytecode Instrumentation:在运行时侵入Java应用程序(2)
来源: https://blogs.sap.com/2016/03/09/java-bytecode-instrumentation-using-agent-breaking-into-java-application-at-runtime/
java达人
2018/12/27
1.3K0
使用代理(Agent)的Java Bytecode Instrumentation:在运行时侵入Java应用程序(2)
java agent使用与agent内存马
本质是一个jar包中的类,有两种实现,第一种是通过permain()函数实现。这种javaagent会在宿主程序的main函数的启动前启动自己premain函数,这时候会得到一个Instrumentation对象,我们可以通过Instrumentation对象对还未加载的class进行拦截与修改。
红队蓝军
2022/05/17
1.2K0
java agent使用与agent内存马
谈谈Java Intrumentation和相关应用
  对于Java 程序员来说,Java Intrumentation、Java agent这些技术可能平时接触的很少,听上去陌生但又好像在哪里见到过。实际上,我们日常应用的各种工具中,有很多都是基于他们实现的,例如常见的热部署(JRebel, spring-loaded)、各种线上诊断工具(btrace, Greys)、代码覆盖率工具(JaCoCo)等等。   本文会介绍 Java Instrumentation及其相关概念,会涉及到的名词包括:
JavaEdge
2020/05/27
1.1K0
谈谈Java Intrumentation和相关应用
Java 调试工具、热部署、JVM 监控工具都用到了它
我们平时写 Java Agent 的机会确实不多,也可以说几乎用不着。但其实我们一直在用它,而且接触的机会非常多。下面这些技术都使用了 Java Agent 技术,看一下你就知道为什么了。
猿天地
2019/09/25
9900
Java 调试工具、热部署、JVM 监控工具都用到了它
JVMTM Tool Interface:JVM源码分析之javaagent原理完全解读
本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员,而且agent都是用Java编写的,不需要太多的C/C++编程基础,不过这篇文章里也会讲到JVMTIAgent(C实现的),因为javaagent的运行还是依赖于一个特殊的JVMTIAgent。
一个会写诗的程序员
2020/05/18
1.7K0
JVMTM Tool Interface:JVM源码分析之javaagent原理完全解读
java运行时创建或修改类-JavaAgent
在运维监控系统开发过程中我们往往需要在特定的方法出入口进行记录日志、采集参数,甚至在特定场景下需要对方法的出入参数或者整个方法逻辑进行重写。目前市面上开源的APM系统主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是参考Google的Dapper实现的。个人在项目中主要使用skywallking,在java、golang等多语言中有过实践,所以这里主要记录自己在java项目中使用skywallking的一些心得和笔记。
lelezc
2023/09/21
6730
java agent使用与agent内存马
本质是一个jar包中的类,有两种实现,第一种是通过permain()函数实现。这种javaagent会在宿主程序的main函数的启动前启动自己premain函数,这时候会得到一个Instrumentation对象,我们可以通过Instrumentation对象对还未加载的class进行拦截与修改。
红队蓝军
2022/04/13
1.3K0
java agent使用与agent内存马
Java基础知识:探针技术
启动前探针使用方式比较局限,而且每次探针更改的时候,都需要重新启动应用,而主程序之后的探针程序就可以直接连接到已经启动的 jvm 中。可以实现例如动态替换类,查看加载类信息的一些功能。
DioxideCN
2022/08/05
1.5K0
相关推荐
Java Agent(一)、初步认识Instrumentation
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验