Nguyên nhân nhận java.lang.VerifyError


191

Tôi đang điều tra như sau 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)

Nó xảy ra khi máy chủ jboss trong đó servlet được triển khai được khởi động. Nó được biên dịch với jdk-1.5.0_11 và tôi đã cố gắng biên dịch lại với jdk-1.5.0_15 mà không thành công. Đó là quá trình biên dịch chạy tốt nhưng khi được triển khai, java.lang.VerifyError xảy ra.

Khi tôi thay đổi tên phương thức và gặp lỗi sau:

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)

Bạn có thể thấy rằng nhiều chữ ký phương thức được hiển thị.

Chữ ký phương thức thực tế là

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

Tôi đã thử nhìn vào nó javapvà nó cho chữ ký phương thức như nó phải vậy.

Khi các đồng nghiệp khác của tôi kiểm tra mã, biên dịch mã và triển khai nó, họ có cùng một vấn đề. Khi máy chủ xây dựng lấy mã và triển khai nó trên các môi trường phát triển hoặc thử nghiệm (HPUX), lỗi tương tự xảy ra. Ngoài ra, một máy kiểm tra tự động chạy Ubuntu cho thấy lỗi tương tự trong quá trình khởi động máy chủ.

Phần còn lại của ứng dụng chạy ổn, chỉ có một servlet bị lỗi. Bất kỳ ý tưởng nơi để tìm sẽ hữu ích.


1
Tôi đã nhận được nó từ việc sử dụng phiên bản so sánh sai. Mất TUYỆT ĐỐI để tìm ... điều đó thật đau đớn
Tim Boland

1
Tôi đã nhận được nó khi sử dụng chạy ngay lập tức trong studio Android (hotswaps on compile). Tắt nó đã làm công việc.
Serge

Câu trả lời:


188

java.lang.VerifyError có thể là kết quả khi bạn đã biên dịch dựa vào thư viện khác với thời gian bạn đang sử dụng.

Ví dụ, điều này đã xảy ra với tôi khi cố gắng chạy một chương trình được biên dịch dựa trên Xerces 1, nhưng Xerces 2 đã được tìm thấy trên đường dẫn lớp. Các lớp cần thiết (trong org.apache.*namespace) đã được tìm thấy trong thời gian chạy, vì vậy ClassNotFoundExceptionđã không kết quả. Đã có những thay đổi đối với các lớp và các phương thức, do đó các chữ ký phương thức được tìm thấy trong thời gian chạy không khớp với những gì có ở thời gian biên dịch.

Thông thường, trình biên dịch sẽ gắn cờ các vấn đề trong đó chữ ký phương thức không khớp. JVM sẽ xác minh lại mã byte một lần nữa khi lớp được tải và ném VerifyErrorkhi mã byte đang cố làm điều gì đó không được phép - ví dụ: gọi một phương thức trả về Stringvà sau đó lưu trữ giá trị trả về đó trong trường chứa a List.


3
Một điều cần nói thêm, đôi khi đó là lỗi của IDE hoặc thiết bị mà mã byte không đúng. Hãy thử khởi động lại IDE để nhận ra vấn đề đồng bộ hóa. Không xóa và cài đặt lại ứng dụng. Khởi động lại thiết bị cũng có thể giúp đỡ.
ima747

2
Để tìm ra lớp nào là thủ phạm, hãy thêm đối số VM -verbose:classvà sau đó tìm lớp ngay trước khi nó tải java.lang.VerifyError. Điều này sẽ có đường dẫn đến JAR. Sử dụng javapvà so sánh với lớp bạn đang biên dịch. Tôi thấy điều này hữu ích vì lớp được báo cáo lỗi không phải là nguyên nhân thực sự là một trong các đối số.
steinybot

21

java.lang.VerifyError là tồi tệ nhất

Bạn sẽ gặp lỗi này nếu kích thước mã byte của phương thức của bạn vượt quá giới hạn 64kb; nhưng bạn có thể đã nhận thấy điều đó.

Bạn có chắc chắn 100% lớp này không có trong classpath ở nơi khác trong ứng dụng của bạn, có thể trong một jar khác không?

Ngoài ra, từ stacktrace của bạn, mã hóa ký tự của tệp nguồn ( utf-8?) Có đúng không?


Tôi chắc chắn rằng nó không có mặt ở một nơi khác. Đó là 43Kb, đó vẫn là một lớp lớn.
Jeroen Wyseur

Cảm ơn vì bài đăng đó, trong trường hợp của tôi, đó là một mã hóa khác: các tệp XMl của JasperReports lưu mã hóa và phiên bản java, bạn phải đặt cài đặt này phù hợp với cài đặt dự án của bạn (thông qua iReport). Đó là vấn đề ở đây, cảm ơn ý tưởng của bạn với mã hóa! :)
Tobias

Đây là vấn đề của tôi đối với các bài kiểm tra Android, multidexing nó đã sửa nó.
Prakash Nadar

10

Như Kevin Panko đã nói, chủ yếu là do thay đổi thư viện. Vì vậy, trong một số trường hợp, "sạch" của dự án (thư mục) theo sau là một bản dựng thực hiện thủ thuật.


9

Một điều bạn có thể thử là sử dụng -Xverify:allnó sẽ xác minh mã byte khi tải và đôi khi đưa ra các thông báo lỗi hữu ích nếu mã byte không hợp lệ.


8

Tôi đã sửa lỗi này trên Android bằng cách thực hiện dự án tôi đang nhập thư viện, như được mô tả ở đây http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpL LibraryProject

Trước đây, tôi chỉ tham khảo dự án (không biến nó thành thư viện) và tôi đã nhận được Xác minh lạ này.

Hy vọng nó sẽ giúp được ai đó.


2
liên kết không còn nữa, vui lòng sửa nó. cảm ơn
Mahdi Rashidi

8

ConfirmError có nghĩa là tệp lớp chứa mã byte đúng về mặt cú pháp nhưng vi phạm một số hạn chế về ngữ nghĩa, ví dụ như mục tiêu nhảy vượt qua ranh giới phương thức.

Về cơ bản, một ConfirmError chỉ có thể xảy ra khi có lỗi trình biên dịch hoặc khi tệp lớp bị hỏng theo một cách khác (ví dụ: thông qua RAM bị lỗi hoặc HD bị lỗi).

Hãy thử biên dịch với một phiên bản JDK khác và trên một máy khác.


5

Trong trường hợp của tôi, dự án Android của tôi phụ thuộc vào một dự án Java khác được biên dịch cho Java 7. java.lang.VerifyError biến mất sau khi tôi thay đổi Mức tuân thủ trình biên dịch của dự án Java đó thành 6.0

Sau đó tôi phát hiện ra rằng đây là sự cố Dalvik: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE


1
Dalvik chỉ là phiên bản phân nhánh của Java6 nên không có tính năng Java7 nào!
Jeroen Wyseur

4

Tôi đã gặp vấn đề này do pack200 xáo trộn một tập tin lớp. Một chút tìm kiếm đã bật lỗi java này lên. Về cơ bản, thiết lập --effort=4gây ra vấn đề biến mất.

Sử dụng java 1.5.0_17 (mặc dù nó đã bị cắt xén trong mỗi biến thể của java 1.5 mà tôi đã thử).


3

Tôi đã sửa một vấn đề java.lang.VerifyError tương tự bằng cách thay thế

        catch (MagickException e)

với

        catch (Exception e)

nơi MagickExceptionđược xác định trong một dự án thư viện (trong đó dự án của tôi có sự phụ thuộc).

Sau đó tôi đã có một java.lang.NoClassDefFoundErrorlớp học từ cùng một thư viện (được sửa theo https://stackoverflow.com/a/9898820/755804 ).


1
Điều này hiệu quả với tôi ... Tôi thực sự muốn tìm ra lỗi gì ngoài việc "thay thế tôi bằng một ngoại lệ chăn và tôi sẽ làm việc".
Alex Hart

@AlexHart nó dành cho Android, nhưng có thể logic tương tự sẽ áp dụng cho Java doanh nghiệp: stackoverflow.com/a/36814155/253468
TWiStErRob

2

Điều này có thể xảy ra trên Android khi bạn đang cố tải một thư viện được biên dịch dựa trên JDK của Oracle.

Đây là vấn đề đối với máy khách HTTP Ning Async.


Bạn đã tìm thấy giải pháp nào chưa @MartinKonicek
Abimbola Esuruoso

2

Trong trường hợp của tôi, tôi đã phải loại bỏ khối này:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Nó đã hiển thị lỗi gần Fragment.showDialog()cuộc gọi phương thức.


2

Ví dụ tối thiểu tạo ra lỗi

Một khả năng đơn giản là sử dụng Jasmin hoặc chỉnh sửa thủ công mã byte bằng trình chỉnh sửa tệp nhị phân.

Cho phép tạo voidphương thức mà không có returnlệnh (được tạo bởi return;câu lệnh trong Java), mà JVMS nói là bất hợp pháp.

Trong Jasmin chúng ta có thể viết:

.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

Sau đó chúng tôi làm javac Main.jjavap -v Mainnói rằng chúng tôi đã biên soạn:

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

Vì vậy, thực sự không có hướng dẫn trở lại.

Bây giờ nếu chúng ta cố gắng chạy, java Mainchúng ta sẽ nhận được:

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)

Lỗi này không bao giờ có thể xảy ra trong Java thông thường, vì trình biên dịch Java thêm một ẩn returncho voidcác phương thức cho chúng ta. Đây là lý do tại sao chúng ta không cần phải thêm một returnđể chúng tôi mainphương pháp. Bạn có thể kiểm tra điều này với javap.

Liên doanh

ConfirmError xảy ra khi bạn cố chạy một số loại tệp lớp bất hợp pháp theo quy định của JVMS 7 chương 4.5

JVMS nói rằng khi Java tải một tệp, nó phải chạy một loạt các kiểm tra để xem tệp lớp đó có ổn không trước khi chạy nó.

Các lỗi như vậy không thể được tạo ra trên một chu trình biên dịch và chạy mã Java đơn, bởi vì JVMS 7 4.10 nói :

Mặc dù trình biên dịch cho ngôn ngữ lập trình Java chỉ phải tạo ra các tệp lớp thỏa mãn tất cả các ràng buộc tĩnh và cấu trúc [...]

Vì vậy, để xem một ví dụ thất bại tối thiểu, chúng ta sẽ cần tạo mã nguồn mà không cần javac.


1

Trang này có thể cung cấp cho bạn một số gợi ý - http://www.zanthan.com/itymbi/archives/000337.html

Có thể có một lỗi tinh vi trong cơ thể của phương thức đó mà javac không phát hiện ra. Khó chẩn đoán trừ khi bạn đăng toàn bộ phương pháp tại đây.

Bạn có thể bắt đầu bằng cách khai báo càng nhiều biến càng tốt ... cuối cùng có thể đã bắt được lỗi được đề cập trên trang web zanthan và thường là một cách thực hành tốt.


1
Anh chàng đó đã gặp lỗi trình biên dịch vào năm 2002, nhưng lỗi đó đã được sửa từ đó.
Kevin Panko

1

Trong trường hợp của tôi, dự án A của tôi có sự phụ thuộc vào người khác, giả sử X (A đang sử dụng một số lớp được định nghĩa trong X). Vì vậy, khi tôi thêm X làm dự án tham chiếu trong đường dẫn xây dựng của A, tôi đã gặp lỗi này. Tuy nhiên, khi tôi loại bỏ X là dự án được tham chiếu và bao gồm jar của X là một trong các thư viện, vấn đề đã được giải quyết.


1

Kiểm tra nhiều phiên bản của cùng một tệp jar trên đường dẫn lớp của bạn.

Ví dụ: tôi đã có opennlp-tools-1.3.0.jar và opennlp-tools-1.5.3.jar trên đường dẫn lớp của tôi và gặp lỗi này. Giải pháp là xóa opennlp-tools-1.3.0.jar.



1

Một lý do khác cho lỗi này có thể là sự kết hợp của AspectJ <= 1.6.11 với JRE> 6.

Xem Bug Eclipse 353467vé Kieker 307 để biết chi tiết.

Điều này đặc biệt đúng khi mọi thứ hoạt động tốt trên JRE 6 và chuyển sang JRE7 phá vỡ mọi thứ.


1

Nó cũng có thể xảy ra khi bạn có rất nhiều mô-đun nhập khẩu với maven. Sẽ có hai hoặc nhiều lớp có cùng tên (cùng tên đủ điều kiện). Lỗi này là kết quả của sự khác biệt về giải thích giữa thời gian biên dịch và thời gian chạy.


1

Nếu bạn đang di chuyển sang java7 hoặc sử dụng java7 thì nhìn chung lỗi này có thể được nhìn thấy. Tôi đã phải đối mặt với các lỗi trên và phải vật lộn rất nhiều để tìm ra nguyên nhân gốc, tôi sẽ đề nghị thử thêm đối số JVM "-XX: -UseSplitVerifier" trong khi chạy ứng dụng của bạn.


1

Sau khi cập nhật Gradletrong Android Studio 3.6.1 sự cố đã xảy ra trên API 19 trong bản phát hành.

Có một lỗiGlide thư viện . Giải pháp là viết lại proguard-Rules.txt .

Cũng hạ cấp Gradlecông trình ( classpath 'com.android.tools.build:gradle:3.5.3'), nhưng đó là một giải pháp lỗi thời, không sử dụng nó.


0

Mặc dù lý do được Kevin đề cập là chính xác, nhưng tôi chắc chắn sẽ kiểm tra bên dưới trước khi chuyển sang thứ khác:

  1. Kiểm tra cglibstrong classpath của tôi.
  2. Kiểm tra các hibernatephiên bản trong classpath của tôi.

Rất có thể là việc có nhiều phiên bản hoặc xung đột của bất kỳ điều nào ở trên có thể gây ra sự cố không mong muốn như vấn đề được đề cập.


0

java.lang.VerifyError có nghĩa là mã byte được biên dịch của bạn đang đề cập đến thứ mà Android không thể tìm thấy. Điều này xác minhError Chỉ phát hành cho tôi với kitkat4.4 và phiên bản nhỏ hơn không có trong phiên bản trên mà thậm chí tôi đã chạy cùng một bản dựng trong cả hai Thiết bị. Khi tôi sử dụng trình phân tích cú pháp jackson json của phiên bản cũ hơn, nó hiển thị 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.+'

Sau đó, tôi đã thay đổi Dependancy thành phiên bản 2.2 mới nhất thành 2.7 mà không có thư viện cốt lõi , sau đó nó hoạt động. có nghĩa là Phương thức và các nội dung khác của lõi được chuyển sang phiên bản mới nhất của Databind2.7 . Điều này khắc phục các vấn đề của tôi.

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

Làm thế nào để bạn biết JAR nào cần tìm?
Siddharth

1
jackson-core: 2.2. + đã trở thành di sản. vì vậy chúng ta cần sử dụng databind: 2.7.0-rc3, chú thích: 2.7.0-rc3 hoặc phiên bản mới nhất. 2 này là đủ, tránh jackson-core: 2.2. +. Tôi đã nhận được một số xác minh vào thời điểm đó. trong khi sử dụng phiên bản 2.7 trở lên, nó không hiển thị lỗi đó
anand krish

0

vui lòng xóa mọi tệp jar không sử dụng được và thử chạy. và công việc của nó đối với tôi, tôi đã thêm một tệp jar jcommons và một tệp jar jcommons.1.0.14 khác để loại bỏ jcommons và nó hoạt động với tôi


0

ghi vào hồ sơ:

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

vào phụ thuộc tiếp theo: <module name="sun.jdk"/>


-1

Trong trường hợp của tôi, tôi đã nhận được lỗi xác minh với dấu vết ngăn xếp bên dưới

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)

Tôi đã giải quyết nó bằng cách xóa mục nhập classpath cho commons-codec-1.3.jar, có một sự không phù hợp trong phiên bản của jar này với cái đi kèm với Jasper.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.