StackMap attribute cannot be parsed for classes less then Java 6.
The error can be reproduced by the following code:
ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Foo", null, "java/lang/Object", null);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "bar", "()V", null, null);
mv.visitCode();
Label start = new Label(), end = new Label(), exception = new Label(), ret = new Label();
mv.visitTryCatchBlock(start, end, exception, "java/lang/Throwable");
mv.visitLabel(start);
mv.visitInsn(Opcodes.NOP);
mv.visitLabel(end);
mv.visitJumpInsn(Opcodes.GOTO, ret);
mv.visitLabel(exception);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitInsn(Opcodes.POP);
mv.visitLabel(ret);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
cw.visitEnd();
new ClassReader(cw.toByteArray()).accept(new ClassVisitor(Opcodes.ASM7) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return new MethodVisitor(Opcodes.ASM7) { };
}
}, 0);
If the class file version is changed to V1_6
, the processing works fine.
This can be a problem since some Java agent vendors write instrumentations without regarding the class file version of a class and always add stack map frames. The JVM ignores the attribute in this case but it would be great if ASM could retain in as it is written to the class file (or at least throw an exception when the attribute that cannot be read later is written to begin with).