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

2024-06-10 17:58

本文主要是介绍Instrumentation与ClassFileTransformer--字节码转换工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一个代理实现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效果相同。

      这篇关于Instrumentation与ClassFileTransformer--字节码转换工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



      http://www.chinasem.cn/article/1048868

      相关文章

      Java实现字节字符转bcd编码

      《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

      使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

      《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

      Java实现将HTML文件与字符串转换为图片

      《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

      Python中Json和其他类型相互转换的实现示例

      《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

      Python实战之SEO优化自动化工具开发指南

      《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

      使用Java读取本地文件并转换为MultipartFile对象的方法

      《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

      MySQL慢查询工具的使用小结

      《MySQL慢查询工具的使用小结》使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下... 目录一、启用慢查询日志1.1 编辑mysql配置文件1.2 重启MySQL服务二、配置动态参数(可选)三、分析慢查

      基于Python实现进阶版PDF合并/拆分工具

      《基于Python实现进阶版PDF合并/拆分工具》在数字化时代,PDF文件已成为日常工作和学习中不可或缺的一部分,本文将详细介绍一款简单易用的PDF工具,帮助用户轻松完成PDF文件的合并与拆分操作... 目录工具概述环境准备界面说明合并PDF文件拆分PDF文件高级技巧常见问题完整源代码总结在数字化时代,PD

      Python按照24个实用大方向精选的上千种工具库汇总整理

      《Python按照24个实用大方向精选的上千种工具库汇总整理》本文整理了Python生态中近千个库,涵盖数据处理、图像处理、网络开发、Web框架、人工智能、科学计算、GUI工具、测试框架、环境管理等多... 目录1、数据处理文本处理特殊文本处理html/XML 解析文件处理配置文件处理文档相关日志管理日期和

      使用Python开发一个Ditto剪贴板数据导出工具

      《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3