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;
    }
};

これを修正します。他の回答も更新します。