往期回顾:
字节码增强常见问题系列(一)| 记一次多个JavaAgent同时使用的类增强冲突问题及分析
一、前言
当前市面上JavaAgent广泛被用于解决各种场景的问题,包括服务治理、链路追踪等。各大厂商和开源社区也都推出了自己的JavaAgent产品,例如Skywalking、阿里的JVM-Sandbox、Sermant等。用户在真实生产环境中可能会采用多个JavaAgent产品,不同的JavaAgent产品可能采用不同的字节码增强框架(ASM、Javassist、ByteBuddy、CGLIB),而在使用不同的字节码增强框架时,可能会出现各种冲突问题,这些冲突可能导致字节码增强失效、应用程序无法启动等问题。即使是使用相同的字节码增强框架也可能会出现冲突问题。对用户而言,在生产环境引入多个不同或者相同的字节码增强框架而不出现兼容性问题尤为重要。在上一期中,我们从字节码增强的底层逻辑角度分析了多个Java Agent加载冲突的问题。本期我们将重点介绍在使用多个字节码增强框架时可能遇到的兼容性问题,并结合我们的经验给出相应的解决方式以及合理的规避手段。
二、常见的字节码增强框架
ASM是基于访问者模式封装的字节码增强框架,可以生成二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。由于AMS是在虚拟机指令层面进行字节码操作,需要开发者熟悉JVM的各种指令集。
Javassist是基于ASM进行二次开发的框架,在AMS的基础上屏蔽了JVM指令集的概念,提供了易于使用的高级 API,使开发者能够动态地创建、修改、分析Java类。但Javassist的增强逻辑采用的是硬编码形式,在开发过程中无法进行debug。
ByteBuddy 是一个简单而强大的字节码操作库,可以与 Java Agent 结合使用来实现动态修改和增强类的字节码。它提供了易于使用的 APIÿ