Wie überwinde ich den "VerifyError: Expecting a Stackmap Frame" für eine JDK 7/8-Anwendung?

Ich verwende eine ASM 5.0.3-Bytecode-Änderungsbibliothek mit Tomcat 8 und JDK 8.

Meine Absicht ist es, Bytecode erfolgreich in alle Klassen einzufügen. Ich bin jedoch auf folgenden Fehler gestoßen:

java.lang.VerifyError: Expecting a stackmap frame at branch target 18
Exception Details:
  Location:
    com/sun/crypto/provider/SunJCE.getInstance()Lcom/sun/crypto/provider/SunJCE; @0: getstatic
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: b200 0bc7 000b bb00 3659 b700 0cb0 b200
    0x0000010: 0bb0 bf                                
  Exception Handler Table:
    bci [0, 18] => handler: 18
  Stackmap Table:
    append_frame(@14,Integer)

            at java.lang.Class.getDeclaredConstructors0(Native Method)
            at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
            at java.lang.Class.getConstructor0(Unknown Source)
            at java.lang.Class.newInstance(Unknown Source)
            at sun.security.jca.ProviderConfig$2.run(Unknown Source)
            at sun.security.jca.ProviderConfig$2.run(Unknown Source)
           ......Some more uninteresting lines in the stack trace.......
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:310)
            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:484)

Die wichtigsten Teile des Codes, den ich zum Aufrufen der ASM-Methoden verwendet habe, lauten wie folgt:

ClassWriter classWriter = new  ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);

classReader.accept(myClassVisitor, ClassReader.EXPAND_FRAMES);

Der obige Code funktioniert perfekt mit der Bytecode-Änderung einer JDK 6-Anwendung. Der Fehler wird nur für JDK 7- und JDK 8-Anwendungen angezeigt.

Verschiedene Blog-Posts und Stackoverflow-Posts verweisen auf die Verwendung der Flags -XX: -UseSplitVerifier oder -noverify. Dies scheint jedoch eine kurzfristige Problemumgehung zu sein, zumal das Flag -XX: -UseSplitVerifier in JDK 8 veraltet ist. Ich möchte eine dauerhafte Lösung erreichen, anstatt mich auf ein Flag zu verlassen, das in zukünftigen Java-Versionen möglicherweise nicht mehr unterstützt wird.

Danke im Voraus

Bearbeiten In Bezug auf Adams freundlichen Vorschlag, @ zu verwendCOMPUTE_FRAMES Anstatt vonCOMPUTE_MAXS, dieser LinkASM - java.lang.VerifyError: Überlauf des Operandenstapels Ausnahme fasst die bisherigen Fehler mit @ zusammCOMPUTE_FRAMES. Derzeit kann ich bei JDK 7/8 weder mit noch mit @ fortfahreCOMPUTE_MAXS oderCOMPUTE_FRAMES.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage