- 开发工具
- 后端
【免费下载链接】byte-buddy
Runtime code generation for the Java virtual machine.
Byte Buddy 是专注于 JVM 运行时字节码生成与修改的 Java 库,其根目录下的 release-notes.md 完整记录了从 2014 年首个版本 0.1 到 2026 年 9 月 1.18.14 的全部版本迭代。本文以这份发布记录为主体脉络,结合仓库内的核心源码、构建配置与插件文档,系统梳理 Byte Buddy 十余年间的功能演进、对新版 Java 的适配策略、Agent 与构建工具链的成熟过程,帮助读者理解该库当前能力的来龙去脉,并掌握如何利用发布记录反查具体功能的实现位置。
版本时间线概览:十年演进一目了然
从 release-notes.md 可以还原出完整的版本节奏:
- 2014 年:0.1 首个正式发布,0.2 引入
@SuperCall语义调整与 Java 8 默认方法支持,0.3 增加类型重定义(redefinition)与重基(rebasing)、HotSwap 与 Java agent 接入能力,0.4 引入TypePool抽象与AnnotationDescription中间表示,0.5 推出AgentBuilderAPI 与ElementMatcher匹配 DSL。 - 2015 年:0.6 系列大规模重构命名(
Instrumentation→Implementation、Field→FieldProxy),0.7 系列为泛型支持(generic types)、桥接方法(bridge methods)、MethodGraph.Compiler铺路,同年 10 月 Byte Buddy 获得 Oracle 颁发的 Duke's Choice 奖。 - 2016 年:1.0.0 正式版支持类型注解(type annotations);1.3 系列集中打磨
Advice组件(entry/exit advice、异常抑制、帧计算);1.4 系列完善AgentBuilder的 redefinition/retransformation 策略、TypePool惰性解析与 Jigsaw 模块初步支持。 - 2017—2019 年:1.6 引入
InjectingClassLoader与 Java 9 模块适配;1.7 推出MemberSubstitution、MemberRemoval;1.8 系列新增ClassWriterStrategy、ClassFileBufferStrategy,并将字节码基线下调至 Java 5;1.9 引入Plugin.Engine静态增强引擎,重做 Maven/Gradle 构建插件,加入 JNA 驱动的 attach 模拟机制。 - 2020—2022 年:1.10 支持 Java 16、sealed types、records;1.11 引入
JavaDispatcher、AccessControllerPlugin、Advice.Exit/Local注解;1.12 完善MemberSubstitution.Step、引入ConstantValueAPI、新增 Gradle 增量构建与 Android 插桩;1.14 推出AsmClassWriter/AsmClassReader抽象与PatchMode。 - 2023—2026 年:1.15 支持 multi-release JAR 与
ByteBuddyJarsTask;1.16 集成 JDK Class File API;1.17 引入@Handle、@DynamicConstant注解与LazinessMode;1.18 系列聚焦供应链安全(Sigstore 签名、SBOM)、Kotlin/AGP 支持、Windows ARM64 动态 attach,并确立*-jdk5版本命名新概念。
当前仓库根目录 pom.xml 中的版本为1.18.15-SNAPSHOT,与发布记录的最新正式版 1.18.14 正好衔接,说明 release-notes 覆盖了仓库全部已发布版本。
对新版 Java 的持续适配:类文件版本与 ASM 同步升级
发布记录中占比最大的主题是对新版 Java 的跟进,其节奏基本是「新 JDK 发布 → 更新 ASM → 增加ClassFileVersion常量 → 发布支持版本」:
| 功能支持 | 引入版本 | 发布记录中的依据 |
|---|---|---|
| Java 24(非实验性) | 1.15.4 | 2024-09 条目 |
| Java 23 | 1.14.12 / 1.14.16 | 2024-02 与 2024-05 条目 |
| Java 22 | 1.14.8 | 2023-08 条目 |
| Java 21 | 1.14.3 | 2023-03 条目 |
| Java 20 | 1.12.18 | 2022-10 条目 |
| Java 19 | 1.12.9 | 2022-04 条目 |
| Java 18 | 1.11.6 | 2021-07 条目 |
| Java 17 | 1.10.21 | 2021-02 条目 |
| Java 16(实验性) | 1.10.12 | 2020-06 条目 |
| Java 15(实验性) | 1.10.6 | 2019-12 条目 |
| Java 14 | 1.9.14 | 2019-07 条目 |
| Java 13 | 1.9.7 | 2019-01 条目 |
| Java 12(初步) | 1.8.15 | 2018-07 条目 |
| Java 11(非实验) | 1.9.0 | 2018-09 条目(ASM 7) |
在源码层面,ClassFileVersion.java 定义了从JAVA_V1到JAVA_V28的完整常量,与发布记录中的 Java 版本适配一一对应。构建根目录 pom.xml 中的<version.asm>9.11</version.asm>表明当前基线使用 ASM 9.11,同时内置了 ASM 到 JDK Class File API 的桥接(version.asmjdkbridge),这正是 1.16.0 条目「Include support for JDK Class File API」的实现基础。发布记录还显示,从 1.17.0 起 Byte Buddy 依赖 Class File API 支持来覆盖「此前未知的类文件特性」,而无需等待 ASM 先行支持。
值得注意的兼容性细节:1.18.3 条目提到「在引导类加载器上加载 Byte Buddy 且 multi-release jar 不可用时,避免使用 Class File API」,说明这类桥接是按运行时环境动态降级的。
Advice组件的进化史:从 ASM 适配器到注解驱动的内联插桩
Advice是 Byte Buddy 用于在方法入口/出口注入代码的核心组件,发布记录从 1.3.0 一直跟踪到 1.18.5:
- 1.3.0首次引入 ASM 适配器形式的
Advice; - 1.3.7增加
@Advice.Ignored与@Advice.Origin注解,实现帧信息复用; - 1.3.11支持
@Advice.BoxedReturn、@Advice.BoxedArguments,异常处理从「前置」改为「追加」到既有 handler 之后; - 1.4.8允许 entry advice 通过返回值跳过原方法执行,并允许 advice 方法跨多个类分布;
- 1.5.5重构为基于
StackManipulation与Assigner的架构; - 1.8.12新增
@Advice.Exit与@Advice.Local,支持基于 exit advice 值的重复执行; - 1.11.19增加
@Advice.AssignReturned后处理器,允许 entry/exit 双侧声明@Advice.Local; - 1.14.2修复局部变量数组重映射的偏移计算,
skipOn/repeatOn支持从返回数组中按索引取值; - 1.17.0引入
@Handle与@DynamicConstant,允许在Advice中注入常量池存储的方法句柄与动态常量; - 1.18.5补全了
Advice的hashCode/equals计算中缺失的父类。
源码 Advice.java 完整呈现了这套注解体系:@OnMethodEnter、@OnMethodExit、@This、@Argument、@AllArguments、@Return、@Thrown、@FieldValue、@FieldGetterHandle、@FieldSetterHandle、@SelfCallHandle、@Handle、@DynamicConstant、@Origin、@Enter、@Exit、@Local、@StubValue、@Unused以及AssignReturned子注解(@AsScalar、@ToArguments、@ToAllArguments、@ToThis、@ToFields、@ToReturned、@ToThrown)均为RetentionPolicy.RUNTIME。Advice同时实现了AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper与Implementation两个接口,印证了发布记录中「Advice 可作 ASM 访问器、也可作为Implementation包装器」的双重定位(1.5.3 条目)。
MemberSubstitution:从字段/方法替换到指令级编程
MemberSubstitution允许对类文件中的成员访问进行替换与委托,是发布记录中迭代最密集的组件之一:
- 1.7.0引入首个版本,用于替换字段/方法访问;
- 1.9.2支持委托到匹配到的成员;
- 1.12.8将
Step类型按预期公开,并补充常用默认Step(1.12.23); - 1.13.0API 趋于完整,保留原始调用指令、支持构造器作为替换目标、引入
ConstantValue统一常量解析; - 1.14.0新增
Step.Factory.ForDelegation,实现类似MethodDelegation的代码内委托; - 1.14.19允许在
MemberSubstitution中加载被插桩方法的参数; - 1.17.0支持拦截
invokedynamic指令,并引入@Handle、@DynamicConstant注解。
源码 MemberSubstitution.java 中可见Step<U extends Target>工厂接口(第 1903 行)以及@This、@Argument、@AllArguments、@FieldValue、@Handle、@DynamicConstant、@SelfCallHandle、@FieldGetterHandle、@FieldSetterHandle、@Origin、@Unused、@StubValue、@Current等绑定注解,与 1.14.0「添加 handlers 以利用方法句柄进行字段访问与自调用」的条目相互印证。结合 1.17.3 条目「进一步泛型化MemberSubstitutionAPI」,可以看出该组件正逐步演进为覆盖字段、方法、构造器、invokedynamic的全方位字节码替换工具。
Java Agent 与动态 Attach:多平台、多 JVM 的适配历程
Agent 能力是 Byte Buddy 实现已加载类重定义的基础,发布记录体现了对 HotSpot、OpenJ9/J9、Windows/POSIX 各组合的长期打磨:
- 1.9.15增加基于 JNA 的 HotSpot Windows attach 模拟与 OpenJ9/J9 的 POSIX/Windows attach 模拟;
- 1.9.16支持 Solaris 上的 attach 模拟,修正 POSIX 的 JNA 签名;
- 1.10.1引入
jdk.internal.misc.Unsafe注入 API(AgentBuilder.InjectionStrategy),支持平台缺少jdk.unsupported时仍可注入; - 1.10.9修正 MacOS 临时目录发现;
- 1.11.14增加事后封闭未密封类加载器(seal unsealed class loaders)的能力;
- 1.14.14修复 Windows 服务用户场景下的动态 attach;
- 1.14.18修复
CircularityLock在加锁期间加载类的问题,attach 模拟在无stat命令时改用istat; - 1.18.12通过发布
win32-aarch64原生attach_hotspot_windows库,支持 Windows ARM64 动态 attach; - 1.18.14避免外部 attach 时在派生子进程命令行暴露 agent 参数。
ByteBuddyAgent.java 的类注释给出了标准用法:
java -javaagent:byte-buddy-agent.jar -jar app.jar源码同时定义了Agent-Class、Can-Redefine-Classes、Can-Retransform-Classes、Can-Set-Native-Method-Prefix等 manifest 属性常量(第 87—102 行),对应 1.9.0 条目「为byte-buddy与byte-buddy-agent构件添加module-info.class」及 1.18.1「修复生成的 module-info 以包含新包」等后续完善。Windows ARM64 的原生实现位于 attach_hotspot_windows.c,而VirtualMachine、Attacher、Installer等类共同构成 agent 的安装与外部 attach 基础设施。
构建期增强:Maven、Gradle 与 Android 插件的成熟路径
发布记录显示构建工具链自 1.4.21/1.4.22 引入 Maven 与 Gradle 插件后持续演进:
- 1.9.0引入
Plugin.Engine统一静态增强引擎,Maven/Gradle 插件均改为基于它实现; - 1.12.15支持从 Gradle 插件进行 Android 插桩;
- 1.15.0Android 插件获得标准配置扩展,行为对齐普通 Gradle 插件;
- 1.15.2增加
ByteBuddyJarsTask,支持一次转换多个 jar; - 1.15.11
Plugin.Engine可链接文件而非复制,Android 插件支持变体配置; - 1.16.0
Plugin.Engine支持保留文件夹; - 1.18.9支持 AGP9 及以上版本的 Android 库;
- 1.18.12Gradle 插件自动支持 Kotlin;1.18.13修正 Kotlin 的 classes 目录重定向并兼容旧版 Gradle,任务优先使用 Gradle 任务注册 API。
Maven 插件的实操配置可见 byte-buddy-maven-plugin/README.md,其transformgoal 的标准配置如下:
<build> <plugins> <plugin> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-maven-plugin</artifactId> <version>LATEST</version> <executions> <execution> <goals> <goal>transform</goal> </goals> </execution> </executions> <configuration> <transformations> <transformation> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> <version>LATEST</version> <plugin>net.bytebuddy.build.CachedReturnPlugin</plugin> </transformation> </transformations> </configuration> </plugin> </plugins> </build>该文档还说明:transform-test用于转换测试类,transform-runtime在保留运行时类的同时转换生产类,transform-extended覆盖所有非 test 作用域(对应 1.14.1 条目);插件可通过META-INF/net.bytebuddy/build.plugins文件自动发现(对应 1.12.13 条目)。在 ByteBuddyMojo.java 中可以看到transformations参数要求每个 transformation 的plugin属性必须实现Plugin接口,并可附带 groupId/artifactId/version 坐标。
Gradle 插件侧,byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle 目录下的ByteBuddyPlugin、ByteBuddyTask、ByteBuddyJarsTask、ByteBuddyJarTask、KotlinByteBuddyTaskConfiguration等类,分别对应 1.18.12 的 Kotlin 自动支持与 1.15.2 的ByteBuddyJarsTask多 jar 转换能力。
供应链安全与稳定性:1.18 系列的主题词
1.18 系列集中体现了 Byte Buddy 在供应链安全与抗畸形输入方面的投入:
- 签名与材料:1.18.12 为发布构件加入 SBOM;1.18.13 确保 SBOM 实际包含在发布构件中;1.18.14 在既有 GPG 签名之外,使用 Sigstore 对所有部署文件签名。根目录 pom.xml 中的
sigstoreprofile 与<release.profiles>extras,gpg,sigstore,gradle-release,multi-release</release.profiles>正是这条链路的构建侧配置。 - 路径穿越防护:1.18.11 检查注入类文件的「可遍历路径」这一假设性攻击向量;1.18.13 防止复制未经转换的 jar 时传播路径穿越;1.18.14 Android 插件保留文件时校验条目名。这对应了 pom.xml 中
sigstore.artifacts.skip等属性所服务的部署流程对输入完整性的整体关注。 - 鲁棒性:1.18.14 限制泛型签名解析的嵌套深度,防止畸形 class 文件导致栈耗尽;1.18.9 在发现 Java 25 及以上时默认禁用
Unsafe使用,而 1.18.10 将这一默认变更推迟到 Java 26 并改善错误信息。
版本命名新概念:*-jdk5后缀与 Java 8 基线
1.18.7 条目宣布了一个影响所有使用者的版本策略变更:「为向后兼容的 jar 引入带*-jdk5后缀的新版本概念,常规 jar 以 Java 8 为基线」。这意味着:
- 带
-jdk5后缀的构件(如byte-buddy-1.18.7-jdk5.jar)保持 Java 5 字节码基线,服务于需要运行在极老 JVM 上的场景; - 常规构件从该版本起以 Java 8 为基线,换取更快的类文件校验与更好的 CDS 支持(1.15.5 条目已为
byte-buddy与 agent 构件引入 multi-release jar 以支持 CDS)。
构建侧的两个发布 profile 与之对应:publish-jdk5与publish-jdk8(见 pom.xml),前者维持1.5的bytecode.main.version,后者将基线提升到 8。README 中的 Java 兼容性表格同样区分了1.18.7(最低 JVM 8)与1.18.7-jdk5(最低 JVM 5)两行。
加载策略与运行时基础设施的沉淀
发布记录同样记录了运行时加载机制的演进,这在 ClassLoadingStrategy.java 中有完整对应:
WRAPPER:新建以目标类加载器为父的ByteArrayClassLoader,可加载存在循环加载依赖的类型,且随类加载器回收而卸载(对应 0.3 条目的 child-first 策略与 0.7 的注入顺序重构);WRAPPER_PERSISTENT/CHILD_FIRST_PERSISTENT:将字节数组暴露为getResourceAsStream资源;CHILD_FIRST:动态类型优先于父类加载器同名类型(不可见而非替换);INJECTION:通过反射把类直接注入既有类加载器,避免新建加载器、获得包级访问能力,但自 Java 11 起受模块封装限制——这与 1.18.9「发现 Java 25 及以上默认禁用 Unsafe」、1.8.16「Java 11+ 通过Unsafe::putBoolean回退启用注入」等条目一脉相承。
此外,Nexus/Installer机制(1.7.0 的net.bytebuddy.nexus.disabled属性、0.7 的 Nexus 多代理注册)与 1.17.6 新增的TypePool.LazinessMode及AgentBuilder便捷支持,共同构成了 agent 场景下类型解析与辅助类型注入的运行时底座。
如何从发布记录反查源码:一种实用检索路径
release-notes 不仅是变更清单,也是定位源码的索引。以「某个功能在哪个类」为例:
- 在 release-notes 中定位引入该功能的版本号;
- 按版本号对照根目录 pom.xml 的发布 profile 确定当时基线;
- 在
byte-buddy-dep/src/main/java/net/bytebuddy/下按功能域检索类名,如asm/目录下的 Advice.java、MemberSubstitution.java、AnnotationRemoval.java(1.17.5 引入),或dynamic/loading/下的 ClassLoadingStrategy.java; - 再通过
src/test/java下同名*Test.java确认行为契约,例如net.bytebuddy.asm.AdviceTest、net.bytebuddy.matcher.*Test等。
这种「发布记录 → 主源码 → 测试用例」的检索链,能帮助读者在阅读新增条目后迅速落到可运行的代码证据上。
结语
从 2014 年的 0.1 到 2026 年的 1.18.14,release-notes.md 勾勒出的是一条「运行时字节码生成核心 + Agent 动态插桩 + 构建期静态增强」三位一体的能力演进路线。理解这条脉络,不仅有助于评估 Byte Buddy 当前 API 的设计动机(如Advice的注解体系为何如此丰富、MemberSubstitution为何逐步覆盖invokedynamic、为何引入*-jdk5版本后缀),也能在阅读源码时快速建立「这个类解决什么问题、从哪个版本开始存在」的坐标系。对于计划将 Byte Buddy 集成到自身框架的开发者而言,这份发布记录连同仓库中的源码与插件配置,是一份可直接对照使用的技术档案。
- 开发工具
- 后端
【免费下载链接】byte-buddy
Runtime code generation for the Java virtual machine.
相关推荐
codex-ppt-skill 演进全解:从 CHANGELOG 透视图片式 PPT 生成的版本脉络、图像后端与运行机制
codex ppt skill 演进全解:从 CHANGELOG 透视图片式 PPT 生成的版本脉络、图像后端与运行机制 本文以 CHANGELOG.md ht
AI 技能人工智能Byte Buddy项目版本更新与技术演进深度解析
Byte Buddy项目版本更新与技术演进深度解析 Byte Buddy作为Java生态中功能强大的字节码操作和代码生成库,其版本迭代过程反映了Java字节码技
开发工具后端Stencil 版本演进全解析:从 CHANGELOG 读懂编译器、运行时与 SSR 的 4.x 发展脉络
Stencil 版本演进全解析:从 CHANGELOG 读懂编译器、运行时与 SSR 的 4.x 发展脉络 Stencil 是一套构建在 TypeScript
开发工具前端前端构建
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考