Skip to content

增强字节码时,没有正确判断 major version,导致 IllegalArgumentException: JSR/RET are not supported with computeFrames option #2897

Closed
@hengyunabc

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

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions