增强字节码时,没有正确判断 major version,导致 IllegalArgumentException: JSR/RET are not supported with computeFrames option #2897
Closed
Description
这个 log4j jar 是非常古老的,做字节码增强时出错:
$ watch org.apache.log4j.Category log
Affect(class count: 0 , method count: 3) cost in 75 ms, listenerId: 1
Enhance error! exception: java.lang.IllegalArgumentException: JSR/RET are not supported with computeFrames option
在 arthas 代码里,会去除 jsr 指令,但为什么失效了呢?
原来是 bytekit 里的代码判断 字节码版本时,没有正确处理有小版本的情况。
public static ClassNode removeJSRInstructions(ClassNode classNode) {
// 据jvm的规范,在 51 及之后版本的字节码里,不允许出现 jsr
if (classNode.version >= 51) {
return classNode;
}
ClassNode result = new ClassNode(Opcodes.ASM9);
classNode.accept(new ClassVisitor(Opcodes.ASM9, result) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
return new JSRInlinerAdapter(mv, access, name, desc, signature, exceptions);
}
});
return result;
}
java 字节码格式里的 version 实际上是两部分组成的: major version 和 minor version 。大部分情况都只有 major version
。
需要到 bytekit 代码中修复: alibaba/bytekit@c8c0430