我发现了 JDK 的一个 BUG

有一次编译,当引用了外部提供的 jar 包时,提示错误的类文件,报错类似这样。

排查问题

根据直观的提示,“错误的类文件”,说明可能是 class 文件损坏。所以检查 class 文件,发现可以反编译,并且这个 jar 包可以正常被执行。这缩小了排查范围,就是编译出错,执行没问题。

注意到,外部提供的 jar 包可能是用 eclipse 编译的。将编译器从 javac 换成 eclipse 编译器 ECJ

此时,使用 javac 不能编译的代码,使用 ECJ 可以编译!这样我们就能准确描述问题了,这是 ECJ 和 javac 的不兼容问题。

使用 ECJ 编译下面这个 java 文件,输出 MyEunm.class 文件后,在新的代码里引用 MyEnum, 然后用 javac 编译新的代码,就会报错!

分析原因

使用 jclasslib 比较 ECJ 与 javac 输出的 MyEunm.class 文件,发现 ECJ 的 class 文件,相比旧版本的 javac,缺少了 Signature attr。说明确实是 ECJ 编译的文件,和 javac 的编译出的文件有区别。

进一步排查

因为 javac 本质上还是一个 java 程序,我们可以直接在 IDEA 中 debug javac。

最终,在代码中,确定:javac 在解析 EJC 编译的 class 时,会发现数组越界的现象。

image.png

上报给 JDT

因为这是 ECJ 和 javc 的不兼容问题,所以上报给 JDT 是合适的。我在 github 上提交了一个 issue ECJ#205,并附上了我的发现。 而 JDT 的维护者分析,ECJ 的行为符合 JVMS 规范,这是 javac 的一个错误!

在 JDT 和 OpenJDK 进行邮件沟通后

image.png

OpenJDK 新建了一个 issue,这是一个 Bug,并认为这不符合 JVMS 4.7.18 和 4.7.19。

image.png

在已经提交的代码中,我们可以发现,OpenJDK 新建了一个 method adjustParameterAnnotations,在 setParameters 前调用,而后面这个函数,正是之前我们断点定位到的位置。

image.png

我们将在 24 版本,看到这个 Bug 被修复。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值