java jvm java-bytecode-asm

java - ¿Cómo supero el "VerifyError: Esperando un marco de mapa de pila" para una aplicación JDK 7/8?



jvm java-bytecode-asm (2)

Solucioné el problema, después de extender la clase ClassWriter y anular el método getCommonSuperClass.

Compruebe este ASM 5.0.3 con Java 1.8 maxStack incorrecto con Java.lang.VerifyError: desbordamiento de pila de operandos

Estoy usando la biblioteca de modificación de código de bytes ASM 5.0.3 con Tomcat 8 y JDK 8.

Mi intención es inyectar bytecode con éxito en todas las clases. Sin embargo, me encontré con el siguiente error:

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)

Las partes clave del código que utilicé para llamar a los métodos de ASM son las siguientes:

ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS); classReader.accept(myClassVisitor, ClassReader.EXPAND_FRAMES);

El código anterior funciona perfectamente con la modificación del código de bytes de una aplicación JDK 6. El error aparece solo para las aplicaciones JDK 7 y JDK 8.

Varias publicaciones de blog y publicaciones de stackoverflow apuntan a usar -XX: -UseSplitVerifier o los distintivos -noverify. Sin embargo, esto parece una solución temporal a corto plazo, especialmente dado que el indicador -XX: -UseSplitVerifier está en desuso en JDK 8. Me gustaría lograr una solución permanente en lugar de confiar en un indicador que finalmente no se admitiría en futuras versiones de Java.

Gracias de antemano.

Editar: En referencia a la amable sugerencia de Adam de usar COMPUTE_FRAMES lugar de COMPUTE_MAXS , este enlace ASM - java.lang.VerifyError: Operand stack overflow Exception resume los errores hasta el momento con COMPUTE_FRAMES . Actualmente, no puedo avanzar en JDK 7/8 con COMPUTE_MAXS o COMPUTE_FRAMES .


Utilice el ClassWriter#COMPUTE_FRAMES para volver a calcular los marcos del mapa de pila. El verificador de código de bytes usa typechecker (stack map) desde JDK 7 , por lo que su código funciona en JDK 6.

Tenga en cuenta que (de COMPUTE_FRAMES ):

computeFrames implica computeMaxs