Причини отримання java.lang.VerifyError


191

Я розслідую наступне 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 показує ту ж помилку під час запуску сервера.

Решта програми працює нормально, лише, що один сервлет вийшов з ладу. Будь-які ідеї, де шукати, були б корисні.


1
Я отримав це з використання неправильної версії ComppareFailure. Взяв ЗАВЖДИ знайти ... це було боляче
Тім Боланд

1
Я отримав це під час використання миттєвого запуску в студії Android (hotswapping при компіляції). Вимкнення його зробило роботу.
Серж

Відповіді:


188

java.lang.VerifyError може бути результатом, коли ви склали з іншої бібліотеки, ніж ви використовуєте під час виконання.

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

Зазвичай компілятор позначить проблеми, коли підписи методів не збігаються. JVM знову перевіряє байт-код, коли завантажується клас, і видає, VerifyErrorколи байт-код намагається зробити щось, чого не можна дозволити - наприклад, викликає метод, який повертається, Stringа потім зберігає це повернене значення у полі, яке містить а List.


3
Додамо одне: іноді це помилка IDE або пристрій, що байт-код невірний. Спробуйте перезапустити IDE, щоб визначити проблему синхронізації. Якщо не вдалося видалити та повторно встановити додаток. Перезавантаження пристрою також може допомогти.
ima747

2
Щоб дізнатися, який клас є винуватцем, додайте аргумент VM, -verbose:classа потім шукайте клас безпосередньо перед завантаженням java.lang.VerifyError. Це матиме шлях до JAR. Використовуйте javapта порівнюйте це з класом, для якого ви складаєте. Я вважаю це корисним, оскільки клас, про який повідомлялося про помилку, не був причиною, адже він був фактично одним із аргументів.
steinybot

21

java.lang.VerifyError найгірші.

Ви отримаєте цю помилку, якщо розмір байтового коду вашого методу перевищує ліміт 64 кб; але ви, мабуть, це помітили.

Ви на 100% впевнені, що цього класу немає у класі в іншому місці вашої програми, можливо, в іншій банці?

Крім того, з вашої стеки, кодування символів вихідного файлу ( utf-8?) Це правильно?


Я впевнений, що його немає деінде. Це 43Kb, це все ще великий клас.
Єроен Візер

Дякую за цю посаду, в моєму випадку це було інше кодування: файли JasperReports XMl зберігають кодування та версію Java, ви повинні встановити це відповідно до налаштувань вашого проекту (через iReport). У цьому і була проблема, дякую за вашу ідею кодування! :)
Тобіас

Це було моєю проблемою для тестів на андроїд, багатозадачність це виправило.
Пракаш Надар

10

Як сказав Кевін Панько, це здебільшого через зміну бібліотеки. Тож у деяких випадках "чистий" проекту (каталогу) з подальшим складанням робить трюк.


9

Ви можете спробувати одне, -Xverify:allщо перевіряє байт-код при завантаженні, а іноді дає корисні повідомлення про помилки, якщо байт-код недійсний.


8

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

Раніше я просто посилався на проект (не перетворюючи його на бібліотеку) і отримував цей дивний VerifyError.

Сподіваюся, це комусь допоможе.


2
посилання більше не доступне, виправте його. спасибі
Махді Рашиді

8

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

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

Спробуйте компілювати з іншою версією JDK та на іншій машині.


5

У моєму випадку мій проект Android залежить від іншого проекту Java, складеного для Java 7. java.lang.VerifyErrorзник, коли я змінив рівень відповідності компілятора цього проекту Java на 6.0

Пізніше я дізнався, що це проблема Dalvik: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE


1
Dalvik - це лише розгалужена версія Java6, тому ніяких функцій Java7 немає!
Джероен Візер

4

У мене виникла ця проблема через pack200 керування файлом класу. Трохи пошуків перетворили цю помилку на Java . В основному, налаштування --effort=4призвело до відмови проблеми.

Використовуючи java 1.5.0_17 (хоча він стикався у кожному варіанті java 1.5, я спробував це).


3

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

        catch (MagickException e)

з

        catch (Exception e)

де MagickExceptionбуло визначено бібліотечний проект (від якого мій проект має залежність).

Після цього я отримав java.lang.NoClassDefFoundErrorприблизно клас з тієї ж бібліотеки (зафіксовано відповідно до https://stackoverflow.com/a/9898820/755804 ).


1
Це працювало для мене ... Я дуже хотів би зрозуміти, яка помилка була, окрім "заміни мене виключенням з ковдрою, і я працюю", хоча
Алекс Харт

@AlexHart це для Android, але , ймовірно , та ж логіка буде застосовуватися для корпоративних Java: stackoverflow.com/a/36814155/253468
TWiStErRob


2

У моєму випадку мені довелося видалити цей блок:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Він показував помилку біля Fragment.showDialog()виклику методу.


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 відбувається під час спроби запуску певних типів незаконного файлу класу, як визначено в розділі 4.5 JVMS 7

JVMS говорить, що коли Java завантажує файл, він повинен виконати ряд перевірок, щоб побачити, що файл класу в порядку, перш ніж запустити його.

Такі помилки неможливо генерувати на одному циклі компіляції та запуску коду Java, оскільки JVMS 7 4.10 говорить :

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

Отже, щоб побачити приклад мінімальної помилки, нам потрібно буде генерувати вихідний код без javac.


1

Ця сторінка може дати вам підказки - http://www.zanthan.com/itymbi/archives/000337.html

У тілі може бути незначна помилка цього методу, яку явак не може помітити. Діагностувати складно, якщо ви не розмістите тут весь метод.

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


1
Цей хлопець потрапив у помилку компілятора ще у 2002 році, але з тих пір ця помилка виправлена.
Кевін Панько

1

Ну а в моєму випадку мій проект A мав залежність від іншого, скажімо, X (A використовував деякі класи, визначені в X). Отже, коли я додав X як еталонний проект на шляху збірки A, я отримав цю помилку. Однак коли я видалив X в якості посиланого проекту і включив банку J в одну з бібліотек, проблема була вирішена.


1

Перевірте наявність декількох версій одного файлу jar на вашому classpath.

Наприклад, я мав opennlp-tools-1.3.0.jar і opennlp-tools-1.5.3.jar на своєму classpath і отримав цю помилку. Рішенням було видалення opennlp-tools-1.3.0.jar.




1

Це також може статися, коли у вас є багато імпорту модулів з maven. Буде два або більше класів, що мають точно однакове ім’я (те ж саме кваліфіковане ім'я). Ця помилка є результатом різниці інтерпретації між часом компіляції та виконанням.


1

Якщо ви переходите на java7 або використовуєте java7, зазвичай ця помилка може бути помічена. Я зіткнувся з вищезазначеними помилками і багато намагався, щоб з'ясувати першопричину, я б запропонував спробувати додати аргумент JVM "-XX: -UseSplitVerifier" під час запуску програми.


1

Після оновлення Gradleв Android Studio 3.6.1 у версії API 19 сталися збої в API 19.

Виникла помилка в Glideбібліотеці . Рішення - переписати proguard-rules.txt .

Також пониження версії Gradleпрацює ( classpath 'com.android.tools.build:gradle:3.5.3'), але це застаріле рішення, не використовуйте його.


0

Хоча причина, яку згадував Кевін, є правильною, але я б точно переконався нижче, перш ніж перейти до чогось іншого:

  1. Перевірте cglibsв моєму класі.
  2. Перевірте hibernateверсії в моєму класі.

Цілком ймовірно, що наявність декількох або суперечливих версій будь-якого з перерахованих вище може спричинити несподівані проблеми, подібні до тієї, про яку йдеться.


0

java.lang.VerifyError означає, що ваш зібраний байт-код посилається на те, що Android не може знайти. Цей verifyError видає мені лише kitkat4.4 та меншу версію, не вищезгадану версію, що навіть я запустив однакову збірку в обох пристроях. коли я використовував jackson json parser старішої версії, він показує 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.+'

Тоді я змінив Dependancy на останню версію 2.2 на 2.7 без основної бібліотеки , тоді вона працює. що означає, що Методи та інший вміст ядра переноситься на останню версію Databind2.7 . Це виправляє мої проблеми.

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

Як ви знаєте, на яку JAR звернути увагу?
Сіддхарт

1
jackson-core: 2.2. + стає спадщиною. тому нам потрібно використовувати databind: 2.7.0-rc3, примітки: 2.7.0-rc3 або останню версію, ніж ця. Цього 2 достатньо, уникайте Джексон-ядра: 2.2. +. Я отримав деякий verifferror до того часу. при використанні версії 2.7+ це не відображає цієї помилки
anand krish

0

видаліть будь-який непридатний файл jar та спробуйте запустити. і його робота для мене я додав файл jar jarcommons, а також ще один jcommons.1.0.14 файл jar, тому видаліть jcommons і його працює для мене



-1

У моєму випадку я отримував перевірку помилки із слідом стека нижче

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.