Причины получения java.lang.VerifyError - PullRequest
184 голосов
/ 19 сентября 2008

Я расследую следующее 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 безуспешно. То есть компиляция выполняется нормально, но при развертывании возникает ошибка 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 выдает ту же ошибку при запуске сервера.

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

Ответы [ 23 ]

2 голосов
/ 17 апреля 2013

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

        catch (MagickException e)

с

        catch (Exception e)

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

После этого я получил java.lang.NoClassDefFoundError о классе из той же библиотеки (исправлено в соответствии с https://stackoverflow.com/a/9898820/755804).

2 голосов

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

Одной простой возможностью является использование 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 к void методы. Вот почему нам не нужно добавлять return к нашим main методам. Вы можете проверить это с помощью javap.

JVMs

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

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

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

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

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

1 голос
/ 18 сентября 2014

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

Это особенно верно, когда на JRE 6 все работает нормально, а простой переход на JRE7 нарушает работу.

1 голос
/ 18 сентября 2014

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

Подробнее см. Eclipse Bug 353467 и Билет Кикера 307 .

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

1 голос
/ 03 мая 2014

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

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

1 голос
/ 31 июля 2013

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

1 голос
/ 19 сентября 2008

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

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

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

1 голос
/ 16 февраля 2016

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

1 голос
/ 04 мая 2015

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

0 голосов
/ 04 января 2018

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

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, в версии этого jar было несоответствие с тем, что поставляется с Jasper.

...