11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

最新版 Byte Buddy 完全支持 Java 11

  • 2018-08-18
  • 本文字数:2918 字

    阅读完需:约 10 分钟

Java 字节码工程库 Byte Buddy 最新版本完全支持 Java 11 以及自 Java 8 以来引入的所有类文件和字节码新特性。其中包括新的 ConstantDynamic(有时称为 condy)特性和 Java 11 Nestmates

InfoQ 采访了 ByteBuddy 的作者 Rafael Winterhalter,以了解更多信息。

InfoQ:感谢你抽出宝贵时间与我们交谈。你能先介绍一下 Byte Buddy 是什么吗?它有哪些功能?可以用于什么样的应用程序?这个项目有多长时间了?开发人员该如何开始使用它?

Rafael Winterhalter Byte Buddy 是一个代码生成库,通过简单的 Java API 定义新类或修改现有类。这个库会生成并操作 Java 字节码。通过处理字节码,它可以与使用任何 JVM 语言编写的代码进行交互,并且可以在 Java 应用程序的运行期间使用该库来修改当前要执行的代码,甚至包括自己的代码。

Byte Buddy 主要被用在其他库和框架中。例如,Hibernate 使用 Byte Buddy 来实现实体代理,Mockito 使用它来生成模拟类。Byte Buddy 也渐渐被用于开发可以改变整个应用程序行为的 Java 代理。APM 工具(例如 Instana)正在使用这类代理收集应用程序运行期间的度量指标。

我从 2014 年开始开发 Byte Buddy,并在 2015 年发布了第一个非 beta 版本。从那以后,它开始获得相当多的关注。现在,这个库每年将近有一亿次的下载量。

要想使用这个库,只需将它添加到项目中,然后使用它的 DSL 生成类。Byte Buddy 的 GitHub 页面和官网都提供了如何创建简单类的示例。网页上还提供了综合性文档,还有很多博客文章、YouTube 和 Vimeo 上的视频资料。

InfoQ:我们来谈谈新版本。最近增加了什么新特性?有没有用户特别要求的新特性?

Winterhalter:在最新的版本中,我一直在尝试支持 Java 11 和 12。不过我的大部分时间都用于添加对 Java 模块系统的支持,这是一条漫漫长路。随着最新版本的发布,对模块系统的支持变得更加稳定,Byte Buddy 甚至会在即将发布的 1.9.0 版本中添加一个 module-info.class。同时,这个库保留了对 Java 6、7 和 8 的兼容性。

用户的特性请求通常包括对较新 Java 版本的支持,因为缺乏对新版本的支持通常会影响项目在较新的 VM 上编译。类似地,还有很多特性请求要求支持 Kotlin 或 Scala 等 JVM 语言,这些语言在字节码转换方面有一些特别之处。如果 Java 语言正在添加新特性,那么就要十分小心,并且通常需要通过扩展 JVM 的功能来实现。其他语言有时会尝试模拟特定的行为,否则 Byte Buddy 会出现问题。

InfoQ:让我们来聊聊新的发布周期——作为一个工具开发者,更快的发布速度和类文件格式变更对你产生了哪些影响?

Winterhalter:对于每个 Java 版本,Byte Buddy 都需要根据 Java 类文件格式的变化进行调整。通常这些变化是很微小的,但也可能很复杂。例如,当 Java 8 发布时,Byte Buddy 必须支持接口的默认方法。这看起来像是一个很小的变化,但它需要进行大量的重构。随着 Java 发布速度的加快,我的工作变得有点令人厌烦,但我不能抱怨,因为这个项目是我当前职业生涯的焦点。

到目前为止我遇到的一个问题是,因为很多库依赖了 Byte Buddy,所以每次新的 Java 主要版本发布后,我都会被要求赶快为他们提供支持。如果我不做出更新,依赖 Byte Buddy 的库就不能使用新的 Java 版本,这阻碍了其他维护者采用 Byte Buddy。与此同时,像 Maven 这样的工具通常也需要一些时间才能支持新的 Java 版本,这也使得我很难快速做出更新。半年时间很快就过去了。但我觉得其他工具开发者已经适应了这种变化。与先前的版本相比,支持 Java 10 到 Java 12 要容易得多,因为每个版本中包含的变更更少了。

InfoQ:Java 11 将 ConstantDynamic 作为一项新特性发布。为什么要这样?它的原理是什么?它与 InvokeDynamic 有关吗?如果有,那是怎样的一种关系?

Winterhalter:Java 开发人员通常使用 static final 关键字来定义常量。不过,Java 类文件中的常量可以是通过符号引用的非类字段。有几种类型已经通过这些符号来表示字面量,例如 Java 字符串。

有了 ConstantDynamic,就可以将任意变量表示为常量池中引用的常量值。使用类文件常量的主要好处是只在第一次使用时才创建,而不是在类加载时创建,而 static final 字段是在类加载时创建的。使用 ConstantDynamic,将来可以避免在 JVM 中进行大量的加载。例如,在 JVM 启动时,它必须初始化 Locale 类,而这个类引用了 JVM 支持的所有语言。这种初始化相当昂贵并且通常是不必要的,因为大多数程序只使用默认语言。通过使用 ConstantDyanmic,未来可以改进核心库,实现更快的 JVM 启动,当然其他库也可以做类似的事情。

截至今天,Java 或其他 JVM 语言还没有公开支持 ConstantDynamic。但因为 JVM 已经提供支持,所以 Byte Buddy 也已经能够在字节码中创建这样的动态常量。动态常量是通过引导(bootstrap)方法创建的,这个方法会返回常量值。在使用常量值的位置需要引用这个引导方法。

我在博文中详细介绍了 ConstantDynamic InvokeDynamic ,以及如何在 Byte Buddy 中使用它们。InvokeDynamic 实际上和 ConstantDynamic 非常类似,区别在于它使用引导方法绑定方法调用而不是常量值。当然,Byte Buddy 也为它提供了 API。

InfoQ:自 Java 8 以来,类文件格式是否有其他重大变化?ByteBuddy 如何应对这些变化?

Winterhalter:除了 ConstantDynamic 之外,JVM 还引入了嵌套伴侣(nest mate)的概念,以便为嵌套类提供更好的方法访问控制。通过在两个类文件中将它们定义为嵌套伴侣,它们就可以获得调用对方私有方法的权限。以前,javac 编译器通过添加 package-private 访问器方法来实现嵌套类的私有方法调用。

Byte Buddy 支持嵌套伴侣,但目前 DSL 不允许更改或添加嵌套伴侣。这是一个比较大的特性,我想在今年晚些时候解决这个问题。

InfoQ:未来会怎样?你对目前路线图中即将推出的特性有何看法?

Winterhalter:目前,几乎所有即将推出的 Java 特性都让我兴奋不已。我最期待的是 Loom,它将提供对 JVM continuation 的原生支持。作为一名软件顾问,我参与的项目通常使用 actor 模型或反应式回调之类的抽象来实现并发。这些应用程序通常会越变越复杂,业务逻辑被埋没在模拟并发性的仪式代码中。这导致业务代码难以重构,因为它们更多地满足了技术需求却忽略了领域逻辑。我希望 Loom 能够让我们不需要在业务代码中显式地使用并发模型。

除了 Loom 之外,我也很期待看到对 Graal 编译器的扩展支持,我认为它是 JVM 能够保持其作为世界上最好运行时之一的重要基石。除了 JIT 编译之外,AOT 编译和原生镜像创建也将扩展 Java 在未来的使用范围。我也希望 Metropolis 项目能够有助于弥合大多数 Java 开发人员的知识与 JVM 的功能之间的一些差距。

InfoQ:你有其他意见或想法想与我们的读者分享的吗?

Winterhalter:我常常觉得一部分 Java 开发人员对甲骨文的管理持怀疑态度,他们觉得模块系统或新发布周期对甲骨文来说可能意味着更大的负担而不是好处。

我认为甲骨文最终解决了很多可能危及平台长期发展的问题。JVM 现在处在一个更好的状态,很多即将发生的变化都是基于这个基础。成为 Java 开发人员是一个激动人心的时刻,我们都有很多值得期待的事情。

查看英文原文 New Version of ByteBuddy Fully Supports Java 11

2018-08-18 03:332707
用户头像

发布了 731 篇内容, 共 405.8 次阅读, 收获喜欢 1966 次。

关注

评论

发布
暂无评论
发现更多内容

GrowingIO Design 组件库搭建之Select组件

GrowingIO技术专栏

select 组件实现 virtualList

别再往收藏夹怼资源了,收好这个视频创作导航网站就够了。

彭宏豪95

效率 视频 导航网站 视频制作

每天学习10个实用Javascript代码片段(一)

devpoint

JavaScript LocalStorage 7月日更

分布式磁盘 KV 存储 - Kvrocks

Kvrocks

RocksDB redis cluster Redis 协议 storage KV存储引擎

来一份全面的面试宝典练练手,看这篇足矣了!

欢喜学安卓

android 程序员 面试 移动开发

🏆【算法数据结构专题】「线程锁算法专项」初探CLH队列锁机制原理分析

洛神灬殇

AQS 数据结构与算法 CLH 7月日更

【LeetCode】从前序与中序遍历序列构造二叉树Java题解

Albert

算法 LeetCode 7月日更

模块一作业

江南巴飞特

接下来的两个月又要忙了

IT蜗壳-Tango

7月日更

《啊哈C语言!》学习笔记(1)

Nydia

辩证|北鲲云和你一起探讨关于生命科学发展的意义

北鲲云

以太坊的 ChainId 与 NetworkId

杰哥的技术杂货铺

区块链 以太坊 ChainId NetworkId

推荐系统的人工调控策略(二十八)

数据与智能

推荐系统 策略模式

模块1.架构设计

脉动

IPFS挖矿算力排行榜?IPFS挖矿排行榜?

第一模块作业

晨晨

架构实战营

垃圾回收器的前世今生

中原银行

垃圾回收

架构实战营模块一作业

王晓宇

架构实战营

你觉得普通程序员和大神程序员有哪些区别

耳东@Erdong

程序员 7月日更

模块2作业

cherrycheek

5分钟速读之Rust权威指南(三十五)状态模式

码生笔谈

rust

连续四年百度Android岗必问面试题!成长路线图

欢喜学安卓

android 程序员 面试 移动开发

架构实战营-模块一作业

李东旭

架构实战营

GitHub霸榜月余的24万字Java面试手册,竟是阿里机密

Java 面试

2021最新一线大厂Java高级架构师面试题总结

Java 程序员 架构 面试

面试官问我会canvas? 我可以绘制一个烟花🎇动画

阿飞

大前端 动画 SVG 数据可视化 canvas

极光开发者周刊【No.0702】

极光JIGUANG

为什么你总是买了很多不需要的东西?

石云升

消费者 7月日更

秋招提前批开始了,一文带你了解,C++ 后台开发知识点及学习路线

奔着腾讯去

学习 程序员 面试 校园招聘 秋招

视频云峰会|“超视频化时代的全景创新” 是什么?

阿里云视频云

阿里云 音视频 视频 视频解码 视频制作

k8s 节点机器重启 CNI IP 未回收

Geek_f24c45

Kubernetes cni

最新版Byte Buddy完全支持Java 11_Java_Ben Evans_InfoQ精选文章