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 controller接口出入参时间序列化转换操作方法(两种)

      《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

      Python实现微信自动锁定工具

      《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

      Java中的工具类命名方法

      《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

      Java对象转换的实现方式汇总

      《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

      python实现svg图片转换为png和gif

      《python实现svg图片转换为png和gif》这篇文章主要为大家详细介绍了python如何实现将svg图片格式转换为png和gif,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录python实现svg图片转换为png和gifpython实现图片格式之间的相互转换延展:基于Py

      MySql match against工具详细用法

      《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

      C#实现将Excel表格转换为图片(JPG/ PNG)

      《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

      基于Java实现回调监听工具类

      《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

      C++使用printf语句实现进制转换的示例代码

      《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

      使用Python构建一个Hexo博客发布工具

      《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加