Я использую библиотеку модификации байт-кода ASM 5.0.3 с Tomcat 8 и JDK 8.Как я могу преодолеть «VerifyError: Expecting framemap frame» для приложения JDK 7/8?
Мое намерение состоит в том, чтобы успешно внедрить байт-код во все классы. Тем не менее, я столкнулся следующее сообщение об ошибке:
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)
Ключевые части кода, который я использовал для того, чтобы вызвать методы ASM являются следующие:
ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
classReader.accept(myClassVisitor, ClassReader.EXPAND_FRAMES);
Приведенный выше код работает отлично с модификацией байткода приложения JDK 6. Ошибка отображается только для приложений JDK 7 и JDK 8.
Различные сообщения в блогах и столбцы stackoverflow указывают на использование -XX: -UseSplitVerifier или -noverify flags. Однако это похоже на краткосрочное обходное решение, особенно учитывая, что флаг -XX: -UseSplitVerifier устарел в JDK 8. Я хотел бы получить постоянное решение, а не полагаться на флаг, который в конечном итоге не будет поддерживаться в будущих выпусках Java.
Заранее спасибо.
Edit: Ссылаясь на любезное предложение Адама использования COMPUTE_FRAMES
вместо COMPUTE_MAXS
, эта ссылка ASM - java.lang.VerifyError: Operand stack overflow Exception суммирует ошибки до сих пор с COMPUTE_FRAMES
. В настоящее время я не могу продвигаться по JDK 7/8 с COMPUTE_MAXS
или COMPUTE_FRAMES
.
Привет Адам, Должен ли я использовать ClassWriter.COMPUTE_FRAMES ** вместо ** ClassWriter.COMPUTE_MAXS? Или это ClassWriter.COMPUTE_FRAMES ** в дополнение к ** вызову ClassWriter.COMPUTE_MAXS? –
Да, используйте 'COMPUTE_FRAMES' вместо просто' COMPUTE_MAXS'. –
Привет Адам: Спасибо за ваше продолжение. Эта ссылка http://stackoverflow.com/questions/34495462/asm-java-lang-verifyerror-operand-stack-overflow-exception суммирует (ошибочные) результаты до сих пор с помощью команды COMPUTE_FRAMES. –