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로 다시 컴파일하려고했습니다. 컴파일이 제대로 실행되지만 배치되면 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를 실행하는 자동 테스트 시스템은 서버 시작 중 동일한 오류를 보여줍니다.

나머지 응용 프로그램은 정상적으로 실행되며 하나의 서블릿 만 고장입니다. 어디를 보아도 도움이 될 것입니다.



답변

java.lang.VerifyError 런타임에 사용중인 라이브러리와 다른 라이브러리에 대해 컴파일 한 경우 결과가 될 수 있습니다.

예를 들어, 이것은 Xerces 1에 대해 컴파일 된 프로그램을 실행하려고 할 때 발생했지만 Xerces 2는 클래스 경로에서 발견되었습니다. org.apache.*네임 스페이스 에서 필수 클래스 가 런타임에 발견되었으므로 결과 ClassNotFoundException아닙니다 . 클래스와 메소드가 변경되어 런타임시 발견 된 메소드 서명이 컴파일시 있던 것과 일치하지 않았습니다.

일반적으로 컴파일러는 메소드 서명이 일치하지 않는 문제를 표시합니다. JVM은 클래스가로드 될 때 바이트 코드를 다시 확인하고 바이트 VerifyError코드가 허용되지 않아야하는 작업을 시도 할 때 (예 :을 반환 String하는 필드에 반환 값을 저장 한 메서드 호출) 호출 합니다 List.


답변

java.lang.VerifyError 최악입니다.

메소드의 바이트 코드 크기가 64kb 제한을 초과하면이 오류가 발생합니다. 그러나 당신은 아마 그것을 알아 차렸을 것입니다.

이 클래스가 응용 프로그램의 다른 경로, 다른 항아리에 클래스 경로에 있지 않다고 100 % 확신합니까?

또한 스택 추적에서 소스 파일의 문자 인코딩 ( utf-8?)이 맞습니까?


답변

Kevin Panko가 말했듯이 대부분 라이브러리 변경 때문입니다. 따라서 어떤 경우에는 프로젝트 (디렉토리)의 “깨끗한”다음에 빌드가 트릭을 수행합니다.


답변

시도 할 수있는 한 가지 방법은 -Xverify:all로드시 바이트 코드를 확인하고 바이트 코드가 유효하지 않은 경우 유용한 오류 메시지를 제공하는 것입니다.


답변

여기에 설명 된대로 라이브러리를 가져오고있는 프로젝트를 만들어 Android 에서이 오류를 수정했습니다. http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject에

이전에는 프로젝트를 참조하고 있었지만 (라이브러리가 아님)이 이상한 VerifyError가 발생했습니다.

그것이 누군가를 돕기를 바랍니다.


답변

VerifyError는 클래스 파일에 구문 적으로 올바른 바이트 코드가 포함되어 있지만 메서드 경계를 넘는 점프 대상과 같은 일부 의미 제한을 위반하는 것을 의미합니다.

기본적으로 VerifyError는 컴파일러 버그가 있거나 클래스 파일이 다른 방식 (예 : RAM 결함이나 HD 실패 등)으로 손상된 경우에만 발생할 수 있습니다.

다른 JDK 버전과 다른 컴퓨터에서 컴파일하십시오.


답변

필자의 경우 내 Android 프로젝트는 Java 7 용으로 컴파일 된 다른 Java 프로젝트에 의존합니다. Java 프로젝트의 java.lang.VerifyError컴파일러 준수 레벨을 6.0으로 변경하면 사라졌습니다.

나중에 이것이 Dalvik 문제라는 것을 알았습니다 : https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE