Instrumentation与ClassFileTransformer--字节码转换工具

【Java核心高阶进阶】39-Javaagent与instrumentation 模块八:Java底层机制 · 第 5 篇如果说字节码增强库(ASM/ByteBuddy)是"手术刀",那么 Javaagent 就是"把手术刀送进手术室"的通道。APM 探针为何能在不改业务代码的前提下监控所有方法?Arthas 为何能在线上诊断 JVM 问题?背后都是 Javaagent + Instrumentation 机制。本章深入 Javaagent 的两种装载方式、的工作机制以及 APM 探针的原理。 阅读详情

一个代理实现ClassFileTransformer接口用于改变运行时的字节码(class File),这个改变发生在jvm加载这个类之前。对所有的类加载器有效。

class File这个术语定义于虚拟机规范3.1,指的是字节码的byte数组,而不是文件系统中的class文件。

接口中只有一个方法:

byte[]
    transform(  ClassLoader         loader,
                String              className,
                Class<?>            classBeingRedefined,
                ProtectionDomain    protectionDomain,
                byte[]              classfileBuffer)
        throws IllegalClassFormatException;

ClassFileTransformer需要添加到Instrumentation实例中才能生效。

获取Instrumentation实例的方法有2种:

  1. 虚拟机启动时,通过agent class的premain方法获得
  2. 虚拟机启动后,通过agent class的agentmain方法获得

一旦agent参数获取到一个instrumentation,agent将会在任意时候调用实例中的方法。

agent应该以jar包的形式存在,也就是说agent所在的类需要单独打包一个jar包,jar包的manifest文件指定agent class。文件中包含Premain-Class属性,agent class类必须实现public static premain 方法,实际应用的main方法在这个方法之后执行。
premain 方法有2种签名,虚拟机优先调用

public static void premain(String agentArgs, Instrumentation inst);

    如果没有上一种,则调用下一种

    public static void premain(String agentArgs); 
    

      通过这个 -javaagent:jarpath[=options] 参数,启动实际应用,就会自带agent。如果agent启动失败,jvm会终止。


      在虚拟机启动后,启动agent需要满足以下条件

      1. agent所在 的jar包的manifest文件中必须包含Agent-Class属性,值为agent class。
      2. agent类必须有public static agentmain方法。
      3. 系统类加载器必须支持添加一个agent的jar包到系统类路径system class path

      这个方法也有2种签名,优先加载第一种,第一种没有,就加载第二种。

      public static void agentmain(String agentArgs, Instrumentation inst); 
      

      public static void agentmain(String agentArgs);

      如果agent是在jvm启动后启动,那么premain就不会执行了。也就是说一个agent的2种方法只会启动一种。premain和agentmain是二选一的。
      agentmain抛出异常,不会导致jvm终止。

      第二种启动方式,先用jps获取进程id,然后启动agentjar包。
      VirtualMachine 在jdk的lib下面的tools.jar中,如果不在classpath的话,要加进去。

      VirtualMachine vm = VirtualMachine.attach("3134");
       try { 
       	vm.loadAgent("/../agent.jar"); 
       } finally 
       { 
       	vm.detach(); 
      }
      

      agent的jar包中manifest中可以有的属性:

      属性作用
      Premain-Class指定代理类
      Agent-Class指定代理类
      Boot-Class-Path指定bootstrap类加载器的搜索路径,在平台指定的查找路径失败的时候生效, 可选
      Can-Redefine-Classes是否需要重新定义所有类,默认为false,可选。
      Can-Retransform-Classes是否需要retransform,默认为false,可选

      有两种ClassFileTransformer,根据canRetransform决定是哪一种。
      在向Instrumentation#addTransformer添加转换器的时候,会指定canRetransform,默认为false。决定retransformation是否可用。

      一旦一个transformer被注册到instrumentation中,每当一个类被定义(ClassLoader.defineClass)或被重新定义(Instrumentation.redefineClasses)时,它都会被调用。

      如果retransformation可用,那么一个类被retransformation(Instrumentation.retransformClasses)时,transformer也会被调用。

      存在多个transformers时,每个transformer会进行链式调用。

      多个transformers调用顺序:

      1. Retransformation不可用的
      2. Retransformation不可用的native 的transformation
      3. Retransformation可用的
      4. Retransformation可用的native 的transformation

      发生retransformations的时候,Retransformation不可用的transformers不会被调用。
      同一种transformers按照注册顺序执行。
      native的transformers通过ClassFileLoadHook提供。

      如果一个transformer不想改变任何代码,那么返回null。否则,应该创建一个新的byte[],不能修改classfileBuffer。

      一个transformer抛出异常,后续的transformer依然会执行,抛异常和返回Null效果相同。

      RISC-V内核移植实战:从零开始手把手实现RT-Thread上下文切换(附GD32VF103代码解析) 本文详细解析了在RISC-V架构上移植RT-Thread实时操作系统的核心步骤,重点聚焦于上下文切换机制的实现。通过对比ARM Cortex-M与RISC-V在中断处理和寄存器管理上的关键差异,并以GD32VF103开发板为例,手把手指导开发者完成libcpu抽象层适配、线程栈初始化以及三种上下文切换方式的代码编写与调试,为嵌入式开发者从ARM转向RISC-V平台提供了实战指南。 阅读详情

      相关推荐

      百度智能云训练图像分割模型+python调用模型并分割图像

      目录 训练模型阶段 发布图像分割API 调用图像分割API 创建应用后显示以下两个代码 在pycharm中可以调用API mask解码 依赖库pycocotools安装步骤: 依赖库urllib2的安装 源码下载: 最近上课听老师介绍了一个训练图像分割模型的网站,把数据集上传之后做图像标注,然后进行训练就能得到准确率等指标。 训练模型阶段 图像分割:https://ai.baidu.com/easydl/vision/ 图像分割-->创建模型-->上传数据--&gt

      icecreamdinner的博客 1388

      Java Agent基础篇

      Java Agent是Arthas使用的技术,是Skywalking使用的技术,是一份十分重要的技术。 课程的稀缺性在此之前,市面上并没有针对Java Agent进行系统介绍的课程。 通过搜索引擎查找,会发现与Java Agent相关的内容大多是个人知识总结分享的内容。这些内容有如下特点:内容质量不一详略程度不一学习难度千差万别总体上来说,学习者很难有一个整体认知、系统学习的过程。 课程的设计目标 在构思课程内容时,本课程带有以下目标:课程学习梯度:从简单到复杂,让学习者有一个循序渐进的理解过程。构造完整、统一的知识体系:不是零散的知识点堆砌,而是有一个统一的贯穿始终的知识框架。具有可操作性的代码示例,不只是讲概念,更注意于实践。课程内容安排 本课程通过四章内容对Java Agent相关知识进行讲解:第一章,介绍Agent Jar的三个组成部分:Manifest、Agent Class和ClassFileTransformer。第二章,介绍Agent Jar的两种启动方式:从命令行启动和使用Attach机制启动。第三章,介绍如何利用Instrumentation API来实现Agent Jar的功能。第四章,Java Agent的应用与技巧。 通过本课程的学习,让同学们更好地建立起一个完整的知识体系:  讲师介绍我叫刘森,南京师范大学研究生毕业,2015年获得信息系统项目管理师(高级),2014年获得系统集成项目管理工程师(中级)。 目前,我的课程都是围绕着“Java字节码”技术展开: 《Java Agent基础篇》是在一个运行JVM当中提供修改字节码的机会《Java ASM系列》(免费课程)是一个操作字节码的类库《Java 8 ClassFile》专注于字节码的理论知识,入选为“51CTO数字化人才证书项目认证课程” 因此,我对字节码技术有较为深入的研究和理解,大家想学习字节码的技术可以找我:字节码技术找刘森,轻松学习又省心~~~ 

      告别JSON!Anthropic发布Tool Calling 2.0,Agent上下文消耗骤降80%

      Anthropic发布ToolCalling 2.0更新,彻底革新AI Agent开发模式。四大核心特性:1)程序化工具调用,允许模型直接输出可执行代码替代JSON交互,降低30-50%Token消耗;2)动态网页过滤,自动清洗网页内容减少24%无效信息;3)工具搜索机制,按需加载工具定义,最高优化80%上下文窗口;4)工具使用示例,通过Few-Shot示范提升复杂表单处理准确率至90%。这一升级将Agent范式从"大模型作为路由"推进到"大模型作为引擎",但需注意代

      老孙 | Ethan Sun 的博客:AI 智能体与 AI 原生软件的工程实践 793

      【Galois工具开发之路】关于ClassFileTransformer的注意点

      该接口是javaagent的方法的入参之一,用于给加载的类添加一个类转换器,确保在类进入main方法之前,对类进行字节码插桩。

      NEWCIH的博客 2227

      [系统安全] 三十二.恶意代码检测(2)常用技术详解及总结

      前文从产业界和学术界分别详细讲解恶意代码攻击溯源的相关知识,在学术界方面,用类似于综述来介绍攻击追踪溯源的不同方法;在产业界方面,主要参考李东宏老师从企业恶意样本分析的角度介绍溯源工作。这篇文章将详细总结恶意代码检测技术,包括恶意代码检测的对象和策略、特征值检测技术、校验和检测技术、启发式扫描技术、虚拟机检测技术和主动防御技术。希望这篇文章对您有所帮助,如果文章中存在错误、理解不到位或侵权的地方,还请告知作者与海涵。且看且珍惜,加油~

      杨秀璋的专栏 1万+

      C++怎么学?零基础也可以,一份完整学习路线图助你搞定!

      提供一条清晰、系统且实践导向的C++学习路径。从基础语法、面向对象、泛型编程、异常处理,逐步深入STL、智能指针、并发编程等现代C++高级特性。无论是新手还是希望提升,通过系统学习与项目实践,助您将理论知识转化为实际解决问题的能力。

      Lion_Long的博客 4022

      Java agent学习

      介绍 JDK1.5开始,Java新增了Instrumentation(Java Agent API)和JVMTI(JVM Tool Interface)功能,允许JVM在加载某个class文件之前对其字节码进行修改,同时也支持对已加载的class(类字节码)进行重新加载(Retransform)。 利用Java Agent这一特性衍生出了APM(Application Performance Management,应用性能管理)、RASP(Runtime application self-protectio

      weixin_45794666的博客 1468

      15、降维算法:原理、实现与应用

      本文深入介绍了多种降维算法,包括线性方法如主成分分析(PCA)和线性判别分析(LDA),以及非线性方法如Sammon映射、t分布随机邻域嵌入(t-SNE)和自编码器。文章通过C++库Dlib和Shogun展示了这些算法的具体实现,并结合图像压缩和数据可视化等实际案例,分析了不同算法的适用场景。此外,还探讨了降维算法的选择策略、优化改进方法以及未来发展趋势,为读者提供了全面的技术理解和应用指导。

      lemon的博客 115

      JVM之类的热替换原理解读

      第二步:写个ClassFileTransformer,利用Javassist等工具进行字节码修改@Override// 在这里利用Javassist等工具修改类的字节码,返回修改后类的字节数组========热替换的核心就在于Instrumentation的两个方法:addTransformer()用来注册类的修改器;retransformClasses()会让类重新加载,从而使得注册的类修改器能够重新修改类的字节码。

      2301_82242670的博客 1428

      ADB加密实例

      主要介绍如何给adb命令增加加密访问

      四儿家的小祖宗的博客 2908

      AI应用架构师:用RAG解决大模型“幻觉”问题的客服架构设计

      在当今的智能客服领域,大语言模型(LLM)凭借流畅的对话能力和强大的理解能力,逐渐取代传统规则式机器人,成为客服系统的核心。但随之而来的“幻觉”问题(即模型编造不存在的信息)却成了致命伤:比如客户问“你们的产品保修期多久”,AI客服可能会自信地回答“3年”,而实际保修期只有1年——这种错误不仅会误导客户,还可能引发投诉、退货甚至法律风险。

      AI天才研究院 914

      Java动态编程之Instrumentation

      从jdk1.5开始提供Instrumentation接口 需求 在不修改代码重新发布的情况下,查看一个线上正运行代码的方法的入参、返回值,或者增加某些日志的打印 解决方案 arthas btrace 具体使用方法可以查看官方文档,那么这些工具的底层是如何实现的呢?没错他们底层都使用了JDK提供的Instrumentation接口。那么Instrumentation接口如何使用呢? 用法 以下内...

      阿呆的专栏 830

      手把手教你在飞牛 NAS 上部署自有图床,含Python调用接口

      📸 想在飞牛 NAS 上部署图床?这篇教程超适合小白!从安装到使用,步骤清晰~

      XiaoqiangClub的博客 2344

      javaAgent Instrumentation与ClassFileTransformer学习总结

      一个代理实现ClassFileTransformer接口用于改变运行时的字节码(class File),这个改变发生在jvm加载这个类之前。对所有的类加载器有效。 class File这个术语定义于虚拟机规范3.1,指的是字节码的byte数组,而不是文件系统中的class文件。 接口中只有一个方法: byte[] transform( ClassLoader loader, String className,

      weixin_44583135的博客 1261

      WINCC7.3破解文件

      WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

      迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

      迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

      字节码增强技术 Byte Buddy 、Javassist、Instrumentation

      ClassFileTransformer接口 一个代理实现ClassFileTransformer接口用于改变运行时的字节码(class File),这个改变发生在jvm加载这个类之前。对所有的类加载器有效。 class File这个术语定义于虚拟机规范3.1,指的是字节码的byte数组,而不是文件系统中的class文件。 接口中只有一个方法: byte[] transform( ClassLoader loader, String

      m0_45406092的博客 6016

      IMSL CNL 7.0.0 (x86-64)Crack

      IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

      从一句神秘日志揭秘Java Agent:字节码增强与JVM监控实战

      Java Agent是Java平台提供的一种无侵入式程序监控与增强技术,它基于Java Instrumentation API实现,允许开发者在JVM加载类时动态修改字节码。这项技术的核心价值在于无需修改源代码即可实现应用性能监控、全链路追踪、热部署等功能,广泛应用于APM工具、微服务治理等场景。通过字节码增强,Agent能够在运行时注入监控逻辑或修复代码缺陷,为系统可观测性和稳定性提供底层支持。本文通过分析线上环境中出现的“Zeus:Bin,你是不是不爱我了?”这一典型日志案例,深入讲解Java Agen

      weixin_34062469的博客 2226

      visio安装包

      Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

      java instrumentation

      Java Instrumentation 是一个强大的工具,允许在运行时动态修改字节码。通过 Java Agent 和。

      qq_62784677的博客 880

      字节码增强要点总结

      (7)注意依赖冲突的问题,比如agent的fatjar中包含了某个第三方的类,业务代码中也包含了相同的第三方但是不同版本的类,由于classloader存在父类优先委派加载的情况,可能会导致类加载异常,所以一般会通过shaded修改第三方类库的包名或者通过classloader隔离,也可以对整个三方包进行名称更改,maven是支持做这样的操作的。需要提示的是,在执行premain()或agentmain()方法前,JVM早已加载了不少类,而这些类的加载事件并没有被拦截,因此也没有被注入。

      weixin_55010563的博客 645

      java之Instrumentation

      java.lang.instrument java.lang.instrument提供了允许java通过代理服务来检测运行在jvm上的程序,检测机制是对方法的字节码进行修改。这一机制实现了虚拟机级别的aop。 通常代理服务被部署为jar文件,jar文件清单中的属性指定将被加载以启动代理的代理类。对于支持命令行接口的实现,可以在命令行指定一个选项来启动代理。实现也支持在vm启动后某一时刻启动代理的机...

      大佬请赐教 1838

      Java Agent(一)、 初步认识Instrumentation

      Instrumentation 是 Java SE 5 引入的一套 API,它允许开发者在运行时修改类的字节码。Java Instrumentation 可以实现在方法插入额外的字节码从而达到收集使用中的数据到指定工具的目的。

      有一只柴犬的专栏 2814

      Java字节码增强技术探秘Agent与Instrumentation的实战应用

      # Java字节码增强技术探秘:Agent与Instrumentation的实战应用## 代理机制基础概念Java Agent是一种能够在JVM启动时或运行时动态修改已加载类字节码的技术。p>在类转换过程中,开发人员可以通过ClassFileTransformer的transform方法获取类的字节码,使用选定的框架进行修改,然后返回修改后的字节码。这个过程对应用程序是完全透明的,被修改的类在运行时表现出的行为与原始类无异,但具有增强的功能特性。因此,必须实现完善的异常处理机制,确保代理的稳定性。

      zhuangxulin的专栏 464

      Java探针技术深入解析:基于Instrumentation和ClassFileTransformer 实现方法耗时监控

      Java探针(Java Agent)技术是JVM提供的一种强大机制,它允许我们在运行时修改或增强已加载的类。这种技术主要依赖于:提供检测Java编程语言代码所需的服务:用于转换类文件的接口Java探针技术为我们提供了一种强大的运行时类修改能力,通过Instrumentation和ClassFileTransformer的组合,可以实现无侵入式的应用监控和增强。这种技术在APM(应用性能监控)、全链路追踪等系统中有着广泛应用。

      用文字记录技术,用分享回馈社区,用坚持见证成长 663

      SkyWalking-2--Java Agent是什么?

      Java Agent:动态字节码修改技术 Java Agent是一种基于JVM的动态字节码修改技术,允许在类加载时或运行时监控和修改程序行为。核心通过Instrumentation接口和ClassFileTransformer实现字节码增强,提供premain(启动时加载)和agentmain(运行时附加)两种入口方式。典型应用包括性能监控、热修复、AOP和安全防护等场景。开发流程涉及编写Agent类、配置MANIFEST.MF和打包JAR。虽然具备非侵入性优势,但也面临兼容性和性能开销等挑战。作为现代Ja

      weisian的博客 3万+
      上一篇: jacoco-sonarjava覆盖率
      下一篇: gson 转 ArrayList
      yayaqwl
      博客等级 码龄13年 28粉丝 103原创
      评论
      成就一亿技术人!
      拼手气红包6.0元
      还能输入1000个字符
       
       条评论被折叠 查看
      添加红包

      请填写红包祝福语或标题

      个

      红包个数最小为10个

      元

      红包金额最低5元

      当前余额3.43元 前往充值 >
      需支付:10.00元
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付元
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值