Причины получения java.lang.VerifyError

Я изучаю следующие java.lang.VerifyError

java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/report/DisplayReportServlet, method: getMonthData signature: (IILjava/util/Collection;Ljava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;Lorg/apache/struts/util/MessageRe˜̴MtÌ´MÚw€mçw€mp:Â"MŒŒ
                at java.lang.Class.getDeclaredConstructors0(Native Method)
                at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
                at java.lang.Class.getConstructor0(Class.java:2671)

Это происходит, когда запускается сервер jboss, в котором развертывается сервлет. Он скомпилирован с помощью jdk-1.5.0_11, и я попытался перекомпилировать его с помощью jdk-1.5.0_15 без succes. То есть компиляция выполняется отлично, но при развертывании происходит событие java.lang.VerifyError.

Когда я изменил имя метода и получил следующую ошибку:

java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/report/DisplayReportServlet, method: getMD signature: (IILjava/util/Collection;Lj    ava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;Lorg/apache/struts/util/MessageResources ØÅN|ØÅNÚw€mçw€mX#ÖM|XÔM
            at java.lang.Class.getDeclaredConstructors0(Native Method)
            at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357
            at java.lang.Class.getConstructor0(Class.java:2671)
            at java.lang.Class.newInstance0(Class.java:321)
            at java.lang.Class.newInstance(Class.java:303)

Вы можете видеть, что показано больше подписи метода.

Фактическая подпись метода

  private PgasePdfTable getMonthData(int month, int year, Collection dayTypes,
                          Collection calendarDays,
                          HashMap bcSpecialDays,
                          Collection activityPeriods,
                          Locale locale, MessageResources resources) throws   Exception {

Я уже пробовал смотреть на него с помощью javap и это дает подпись метода, как и должно быть.

Когда мои другие коллеги проверяют код, компилируют его и развертывают, у них такая же проблема. Когда сервер сборки берет код и развертывает его в средах разработки или тестирования (HPUX), возникает такая же ошибка. Также автоматическая тестовая машина под управлением Ubuntu показывает ту же ошибку при запуске сервера.

Остальная часть приложения работает нормально, только один сервлет не работает. Любые идеи, где искать, будут полезны.

Ответ 1

java.lang.VerifyError может быть результатом, когда вы скомпилировались против другой библиотеки, чем вы используете во время выполнения.

Например, это случилось со мной при попытке запустить программу, которая была скомпилирована против Xerces 1, но Xerces 2 был найден в пути к классам. Необходимые классы (в пространстве имен org.apache.*) были найдены во время выполнения, поэтому ClassNotFoundException был не результатом. Были внесены изменения в классы и методы, так что сигнатуры методов, найденные во время выполнения, не совпадали с тем, что было во время компиляции.

Обычно компилятор будет отмечать проблемы, когда сигнатуры методов не совпадают. JVM снова проверяет байт-код при загрузке класса и бросает VerifyError, когда байт-код пытается сделать что-то, что не должно быть разрешено - например. вызывая метод, который возвращает String, а затем сохраняет это возвращаемое значение в поле, которое содержит List.

Ответ 2

java.lang.VerifyError являются наихудшими.

Вы получите эту ошибку, если размер байт-кода вашего метода превышает лимит в 64 КБ; но вы, вероятно, заметили бы это.

Вы на 100% уверены, что этот класс отсутствует в пути к классам в другом месте вашего приложения, возможно, в другом банке?

Кроме того, из вашего stacktrace является символьная кодировка исходного файла (utf-8?) Правильно ли это?

Ответ 3

Как сказал Кевин Панко, это в основном из-за изменения библиотеки. Поэтому в некоторых случаях "чистый" проект (каталог), за которым следует сборка, делает трюк.

Ответ 4

Я исправил эту ошибку на Android, сделав проект, в котором я импортировал библиотеку, как описано здесь http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject

Раньше я просто ссылался на проект (не делая его библиотекой), и я получал этот странный VerifyError.

Надеюсь, что это поможет кому-то.

Ответ 5

Одна вещь, которую вы можете попробовать, - это использовать -Xverify:all, который проверяет байт-код при загрузке и иногда дает полезные сообщения об ошибках, если байт-код недействителен.

Ответ 6

VerifyError означает, что файл класса содержит байт-код, который является синтаксически правильным, но нарушает некоторые семантические ограничения, например. цель перехода, пересекающая границы методов.

В принципе, VerifyError может возникать только тогда, когда имеется ошибка компилятора или когда файл класса повреждается каким-либо другим способом (например, с помощью неисправной ОЗУ или неудачного HD).

Попробуйте выполнить компиляцию с другой версией JDK и на другой машине.

Ответ 7

В моем случае мой проект Android зависит от другого Java-проекта, скомпилированного для Java 7. java.lang.VerifyError исчез после того, как я изменил уровень совместимости компилятора этого проекта Java на 6.0

Позже я узнал, что это проблема Dalvik: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE

Ответ 8

Я получал эту проблему из-за того, что pack200 искал файл класса. Немного искал этот java bug вверх. В принципе установка --effort=4 заставила проблему уйти.

Использование java 1.5.0_17 (хотя оно появилось в каждом варианте java 1.5, я попробовал его).

Ответ 9

Я установил аналогичную проблему java.lang.VerifyError, заменив

        catch (MagickException e)

с

        catch (Exception e)

где MagickException был определен в проекте библиотеки (на котором мой проект имеет зависимость).

После этого у меня есть java.lang.NoClassDefFoundError о классе из той же библиотеки (исправлено в соответствии с fooobar.com/questions/36797/...).

Ответ 10

Это может произойти на Android, когда вы пытаетесь загрузить библиотеку, которая была скомпилирована против Oracle JDK.

Вот проблема для HTTP-клиента Ning Async.

Ответ 11

В моем случае мне пришлось удалить этот блок:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Появилась ошибка при вызове метода Fragment.showDialog().

Ответ 12

Минимальный пример, который генерирует ошибку

Одна простая возможность - использовать Jasmin или вручную отредактировать байт-код с помощью редактора двоичных файлов.

Позволяет создать метод void без инструкции return (сгенерированной оператором return; в Java), что, по мнению JVMS, является незаконным.

В Жасмине мы могли бы написать:

.class public Main
.super java/lang/Object

.method public static main([Ljava/lang/String;)V
   aload_0 ; Just so that we won't get another verify error for empty code.
.end method

Затем мы делаем javac Main.j и javap -v Main говорит, что мы скомпилировали:

public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0

так что действительно нет инструкции возврата.

Теперь, если мы попытаемся запустить java Main, получим:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: (class: NoReturn, method: main signature: ([Ljava/lang/String;)V) Falling off the end of the code
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)

Эта ошибка никогда не может произойти в Java, поскольку компилятор Java добавляет неявные методы return to void для нас. Вот почему нам не нужно добавлять return к нашим методам main. Вы можете проверить это с помощью javap.

JVMs

VerifyError возникает, когда вы пытаетесь запустить определенные типы незаконного файла класса, как указано JVMS 7 глава 4.5

JVMS говорит, что когда Java загружает файл, он должен выполнить серию проверок, чтобы убедиться, что файл класса в порядке, прежде чем запускать его.

Такие ошибки не могут быть сгенерированы в одном цикле компиляции и запуска кода Java, потому что JVMS 7 4.10 говорит:

Несмотря на то, что компилятор для языка программирования Java должен создавать файлы классов, которые удовлетворяют всем статическим и структурным ограничениям [... ]

Итак, чтобы увидеть пример минимальной ошибки, нам нужно будет сгенерировать исходный код без javac.

Ответ 13

Эта страница может дать вам несколько советов - http://www.zanthan.com/itymbi/archives/000337.html

В теле этого метода может быть тонкая ошибка, которую javac не обнаруживает. Трудно диагностировать, если вы не публикуете весь метод здесь.

Вы можете начать с объявления как можно большего числа переменных в качестве окончательного..., которые поймали бы ошибку, упомянутую на сайте zanthan, и часто являются хорошей практикой в ​​любом случае.

Ответ 14

В моем случае мой проект А имел зависимость от другого, скажем, X (A использовал некоторые классы, определенные в X). Поэтому, когда я добавил X в качестве эталонного проекта в пути сборки A, я получил эту ошибку. Однако, когда я удалил X в качестве ссылочного проекта и включил X jar в качестве одной из библиотек, проблема была решена.

Ответ 15

Проверьте наличие нескольких версий одного и того же файла jar в вашем пути к классам.

Например, у меня был opennlp-tools-1.3.0.jar и opennlp-tools-1.5.3.jar в моем пути к классам и получил эту ошибку. Решение заключалось в удалении opennlp-tools-1.3.0.jar.

Ответ 16

Другой причиной этой ошибки может быть комбинация AspectJ <= 1,6.11 с JRE > 6.

Смотрите Eclipse Bug 353467 и билет Kieker 307 для подробности.

Это особенно актуально, когда все отлично работает на JRE 6, и переход на JRE7 разрывает ситуацию.

Ответ 17

CGLIB < 2.2 с JRE > 6 могут вызывать подобные ошибки, см. "Должен ли я перейти на CGLIB 3.0?" и некоторые комментарии в Spring SPR-9669.

Это особенно актуально, когда все работает отлично на JRE 6 и просто переключается на JRE7, что ломает вещи.

Ответ 18

Это также может произойти, когда у вас много импорта модулей с maven. Будет два или более классов, имеющих одинаковое имя (одно и то же имя). Эта ошибка возникает из-за различий в интерпретации между временем компиляции и временем выполнения.

Ответ 19

Если вы переходите на java7 или используете java7, то обычно эту ошибку можно увидеть. Я столкнулся с ошибками и изо всех сил пытался выяснить причину, я бы предложил попробовать добавить аргумент JVM "- XX: -UseSplitVerifier во время запуска приложения.

Ответ 20

Хотя причина, упомянутая Кевином, верна, но я определенно проверю ниже, прежде чем переходить к чему-то еще:

  • Проверьте cglibs в моем пути к классам.
  • Проверьте версии hibernate в моем пути к классам.

Вероятно, что наличие множественной или противоречивой версии любого из вышеперечисленных может вызвать неожиданные проблемы, такие как тот, о котором идет речь.

Ответ 21

java.lang.VerifyError означает, что ваш скомпилированный байт-код ссылается на то, что Android не может найти. Это verifyError Выдает меня только с kitkat4.4 и меньшей версией, не указанной выше в версии, даже если я запустил одну и ту же сборку в обоих устройствах. когда я использовал парсер jsonson json более старой версии, он показывает java.lang.verifyerror

compile 'com.fasterxml.jackson.core:jackson-databind:2.2.+'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.+'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.2.+'

Затем я изменил зависимость к последней версии от 2,2 до 2,7 без основной библиотеки, тогда она работает. что означает, что методы и другое содержимое core перенесены в последнюю версию Databind2.7. Это исправить мои проблемы.

compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.0-rc3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc3'

Ответ 22

удалите все неиспользуемые файлы jar и попробуйте запустить. и его работа для меня я добавил jcomm файл jar, а также еще один jar файл jcommons.1.0.14, поэтому удалите jcommons и его работу для меня

Ответ 23

записать в файл:

{Wildfly-home}\modules\system\layers\base\org\picketbox\main 

в зависимости следующим образом: <module name="sun.jdk"/>

Ответ 24

В моем случае я получал ошибку проверки ниже трассировки стека

jasperreports-server-cp-6.4.0-bin\buildomatic\build.xml:61: The following error occurred while executing this line:
TIB_js-jrs-cp_6.4.0_bin\jasperreports-server-cp-6.4.0-bin\buildomatic\bin\setup.xml:320: java.lang.VerifyError: (class: org/apache/commons/codec/binary/Base64OutputStream, method: <init> signature: (Ljava/io/OutputStream;ZI[B)V) Incompatible argument to function
    at com.jaspersoft.jasperserver.crypto.KeystoreManager.createKeystore(KeystoreManager.java:257)
    at com.jaspersoft.jasperserver.crypto.KeystoreManager.init(KeystoreManager.java:224)
    at com.jaspersoft.buildomatic.crypto.KeystoreTask.execute(KeystoreTask.java:64)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:169)
    at org.apache.tools.ant.taskdefs.ImportTask.importResource(ImportTask.java:222)
    at org.apache.tools.ant.taskdefs.ImportTask.execute(ImportTask.java:163)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:180)
    at org.apache.tools.ant.ProjectHelper.configureProject(ProjectHelper.java:93)
    at org.apache.tools.ant.Main.runBuild(Main.java:826)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Я решил его устранить, удалив элемент classpath для commons-codec-1.3.jar, в версии этого баннера было несоответствие с тем, что оно поставляется с Jasper.