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

      相关文章

      Python使用OpenCV实现获取视频时长的小工具

      《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

      Linux中压缩、网络传输与系统监控工具的使用完整指南

      《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

      关于集合与数组转换实现方法

      《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

      sqlite3 命令行工具使用指南

      《sqlite3命令行工具使用指南》本文系统介绍sqlite3CLI的启动、数据库操作、元数据查询、数据导入导出及输出格式化命令,涵盖文件管理、备份恢复、性能统计等实用功能,并说明命令分类、SQL语... 目录一、启动与退出二、数据库与文件操作三、元数据查询四、数据操作与导入导出五、查询输出格式化六、实用功

      利用Python脚本实现批量将图片转换为WebP格式

      《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

      基于Python开发Windows屏幕控制工具

      《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

      SQLite3命令行工具最佳实践指南

      《SQLite3命令行工具最佳实践指南》SQLite3是轻量级嵌入式数据库,无需服务器支持,具备ACID事务与跨平台特性,适用于小型项目和学习,sqlite3.exe作为命令行工具,支持SQL执行、数... 目录1. SQLite3简介和特点2. sqlite3.exe使用概述2.1 sqlite3.exe

      基于Python实现一个Windows Tree命令工具

      《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

      使用jenv工具管理多个JDK版本的方法步骤

      《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

      java Long 与long之间的转换流程

      《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c