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
.