ASM BasicInterpreter IllegalStateException

Oct 21 2020

Vi essa pergunta aqui no SO e estou tentando compilar o código a partir da resposta aceita. Infelizmente, continuo recebendo uma IllegalStateException nesta parte do Código:

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

Com o rastreamento de pilha:

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)

A exceção é gerada aqui na classe BasicInterpreter :

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

Tentei herdar o BasicInterpreter, mas continuo recebendo a mesma exceção.

class BasicInterpreterLocal extends BasicInterpreter{} // Throws an IllegalStateException

Tentei com asm 7. *, 8. **, 9.0, mas nada funciona.

Então qual é o problema?. Não consegui encontrar.

Respostas

2 Holger Oct 21 2020 at 22:37

Conforme explicado nesta resposta , as subclasses devem usar o construtor que aceita um número de versão da biblioteca, para determinar o nível de compatibilidade da biblioteca ASM. Parece que a versão 5 da biblioteca ASM, que o código estava usando inicialmente, não verificou esse requisito. Mas você está usando uma versão mais recente (8, aparentemente) da biblioteca que impõe essa regra.

Altere o código para

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

para consertar isso. Também atualizarei a outra resposta.