ASM BasicInterpreter IllegalStateException

Oct 21 2020

ฉันเห็นคำถามนี้ที่นี่ใน SO และฉันกำลังพยายามรวบรวมรหัสจากคำตอบที่ยอมรับ น่าเสียดายที่ฉันได้รับ IllegalStateException ในส่วนนี้ของรหัส:

BasicInterpreter basic = new BasicInterpreter() {
        @Override public BasicValue newValue(Type type) {
            return type!=null && (type.getSort()==Type.OBJECT || type.getSort()==Type.ARRAY)?
                    new BasicValue(type): super.newValue(type);
        }
        @Override public BasicValue merge(BasicValue a, BasicValue b) {
            if(a.equals(b)) return a;
            if(a.isReference() && b.isReference())
                // this is the place to consider the actual type hierarchy if you want
                return BasicValue.REFERENCE_VALUE;
            return BasicValue.UNINITIALIZED_VALUE;
        }
    };

ด้วยการติดตามสแต็ก:

Exception in thread "main" java.lang.IllegalStateException
    at org.objectweb.asm.tree.analysis.BasicInterpreter.<init>(BasicInterpreter.java:66)
    at ConstantTracker$1.<init>(ConstantTracker.java:48)
    at ConstantTracker.<init>(ConstantTracker.java:48)
    at HelloWorld.analyze(HelloWorld.java:37)
    at HelloWorld.main(HelloWorld.java:28)

ข้อยกเว้นถูกยกขึ้นที่นี่ในคลาสBasicInterpreter :

public BasicInterpreter() {
    super(/* latest api = */ ASM8);
    if (getClass() != BasicInterpreter.class) {
      throw new IllegalStateException(); // at this line
    }
  }

ฉันพยายามสืบทอด BasicInterpreter แต่ฉันยังคงได้รับข้อยกเว้นเหมือนเดิม

class BasicInterpreterLocal extends BasicInterpreter{} // Throws an IllegalStateException

ฉันลองกับ asm 7. *, 8. **, 9.0 แต่ไม่มีอะไรได้ผล

แล้วปัญหาคืออะไร?. ฉันไม่พบมัน

คำตอบ

2 Holger Oct 21 2020 at 22:37

ตามที่อธิบายไว้ในคำตอบนี้คลาสย่อยควรใช้ตัวสร้างที่ยอมรับหมายเลขเวอร์ชันไลบรารีเพื่อกำหนดระดับความเข้ากันได้ของไลบรารี ASM ดูเหมือนว่าไลบรารี ASM เวอร์ชัน 5 ที่ใช้โค้ดในตอนแรกไม่ได้ตรวจสอบข้อกำหนดนี้ แต่คุณกำลังใช้ไลบรารีเวอร์ชันใหม่กว่า (เห็นได้ชัดว่า 8) ซึ่งบังคับใช้กฎนี้

เปลี่ยนรหัสเป็น

BasicInterpreter basic = new BasicInterpreter(Opcodes.ASM5) { // <- the crucial point
    @Override public BasicValue newValue(Type type) {
        return type!=null && (type.getSort()==Type.OBJECT || type.getSort()==Type.ARRAY)?
               new BasicValue(type): super.newValue(type);
    }
    @Override public BasicValue merge(BasicValue a, BasicValue b) {
        if(a.equals(b)) return a;
        if(a.isReference() && b.isReference())
            // this is the place to consider the actual type hierarchy if you want
            return BasicValue.REFERENCE_VALUE;
        return BasicValue.UNINITIALIZED_VALUE;
    }
};

เพื่อแก้ไขปัญหานี้ ฉันจะอัปเดตคำตอบอื่น ๆ ด้วย