ASM BasicInterpreter IllegalStateException

Oct 21 2020

J'ai vu cette question ici sur SO et j'essaye de compiler le code à partir de la réponse acceptée. Malheureusement, je continue à recevoir une exception IllegalStateException dans cette partie du code:

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

Avec la trace de pile:

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)

L'exception est déclenchée ici dans la classe BasicInterpreter :

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

J'ai essayé d'hériter de BasicInterpreter mais je continue à recevoir la même exception.

class BasicInterpreterLocal extends BasicInterpreter{} // Throws an IllegalStateException

Je l'ai essayé avec asm 7. *, 8. **, 9.0, mais rien ne fonctionne.

Alors quel est le problème?. Je n'ai pas pu le trouver.

Réponses

2 Holger Oct 21 2020 at 22:37

Comme expliqué dans cette réponse , les sous-classes doivent utiliser le constructeur acceptant un numéro de version de bibliothèque, pour déterminer le niveau de compatibilité de la bibliothèque ASM. Il semble que la version 5 de la bibliothèque ASM, que le code utilisait initialement, n'ait pas vérifié cette exigence. Mais vous utilisez une version plus récente (8, apparemment) de la bibliothèque qui applique cette règle.

Changez le code en

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

pour résoudre ce problème. Je mettrai également à jour l'autre réponse.