web-dev-qa-db-ja.com

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を実行している自動テストマシンでも、サーバーの起動時に同じエラーが表示されます。

残りのアプリケーションは正常に実行されますが、1つのサーブレットのみが故障しています。どこを探すべきかは、役に立つでしょう。

184
JeroenWyseur

Java.lang.VerifyErrorは、実行時に使用しているものとは異なるライブラリに対してコンパイルした場合に結果になる可能性があります。

たとえば、Xerces 1に対してコンパイルされたプログラムを実行しようとしたときに、Xerces 2がクラスパスに見つかりました。必要なクラス(org.Apache.*名前空間内)は実行時に見つかったため、ClassNotFoundExceptionnotの結果でした。クラスとメソッドに変更が加えられたため、実行時に見つかったメソッドシグネチャがコンパイル時に存在したものと一致しませんでした。

通常、コンパイラはメソッドシグネチャが一致しない問題にフラグを立てます。 JVMは、クラスがロードされるとバイトコードを再度検証し、バイトコードが許可されてはならないことを実行しようとするとVerifyErrorをスローします。 Stringを返すメソッドを呼び出し、その戻り値をListを保持するフィールドに格納します。

181
Kevin Panko

Java.lang.VerifyErrorは最悪です。

メソッドのバイトコードサイズが64kbの制限を超えると、このエラーが発生します。しかし、おそらくあなたはそれに気づいたでしょう。

このクラスがアプリケーションの別のクラスパス、おそらく別のjarに存在しないことを100%確信していますか?

また、スタックトレースから、ソースファイルの文字エンコーディング(utf-8?)は正しいですか?

20
p3t0r

ケビン・パンコが言ったように、それは主に図書館の変更によるものです。そのため、場合によっては、プロジェクト(ディレクトリ)の「クリーン」とそれに続くビルドがトリックを行います。

10
Flow

ここで説明するように、ライブラリをインポートするプロジェクトを作成することで、Androidでこのエラーを修正しました http://developer.Android.com/tools/projects/projects-Eclipse.html#SettingUpLibraryProject

以前は、プロジェクトを参照するだけで(ライブラリにしない)、この奇妙なVerifyErrorが発生していました。

それが誰かを助けることを願っています。

8
Tiago

VerifyErrorは、クラスファイルに構文的に正しいバイトコードが含まれていますが、何らかのセマンティック制限に違反していることを意味します。メソッドの境界を越えるジャンプターゲット。

基本的に、VerifyErrorが発生するのは、コンパイラのバグがある場合、またはクラスファイルが他の何らかの方法で破損した場合(たとえば、障害のあるRAMまたはHDの障害)のみです。

別のJDKバージョンと別のマシンでコンパイルしてみてください。

7

あなたが試みるかもしれないことの1つは、ロード時にバイトコードを検証する-Xverify:allを使用することです。

7
Alex Miller

私の場合、Androidプロジェクトは、Java 7用にコンパイルされた別のJavaプロジェクトに依存しています。Java.lang.VerifyErrorは、Javaプロジェクトの

後で、これはDalvikの問題であることがわかりました。 https://groups.google.com/forum/?fromgroups#!topic/Android-developers/sKsMTZ42pwE

5
Michal Vician

Pack200がクラスファイルをマングルしているため、この問題が発生していました。少し検索すると、これが Javaバグ になりました。基本的に、--effort=4を設定すると、問題はなくなりました。

Java 1.5.0_17を使用します(ただし、Java 1.5のすべてのバリアントで発生しましたが、試しました)。

4
Mike Miller

これは、OracleのJDKに対してコンパイルされたライブラリをロードしようとしたときに、Androidで発生する可能性があります。

問題があります Ning Async HTTPクライアントの場合。

2
Martin Konicek

私は同様のJava.lang.VerifyErrorの問題を修正して修正しました

        catch (MagickException e)

        catch (Exception e)

ここで、MagickExceptionはライブラリプロジェクトで定義されています(プロジェクトには依存関係があります)。

その後、同じライブラリのクラスについてJava.lang.NoClassDefFoundErrorを取得しました( https://stackoverflow.com/a/9898820/755804 に従って修正されました)。

私の場合、このブロックを削除する必要がありました。

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Fragment.showDialog()メソッド呼び出しの近くでエラーが表示されていました。

2
ViliusK

エラーを生成する最小限の例

1つの簡単な可能性は、 Jasmin を使用するか、バイナリファイルエディターでバイトコードを手動で編集することです。

JVMSが違法だと言っているvoid命令(Javaのreturn;ステートメントによって生成される)なしでreturnメソッドを作成できます。

ジャスミンでは次のように書くことができます。

.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コンパイラーが暗黙的にreturnvoidメソッドに追加するため、通常Javaで発生することはありません。これが、returnmainメソッドに追加する必要がない理由です。これはjavapで確認できます。

JVMS

JVMS 7 Chapter 4.5 で指定されている特定のタイプの不正なクラスファイルを実行しようとすると、VerifyErrorが発生します。

JVMSは、Javaがファイルをロードするとき、実行する前にクラスファイルが正常であることを確認するために一連のチェックを実行する必要があると言います。

JVMS 7 4.10による :のため、このようなエラーはJavaコードの単一のコンパイルおよび実行サイクルで生成できません。

Javaプログラミング言語用のコンパイラは、すべての静的および構造的制約を満たすクラスファイルのみを生成する必要がありますが[...]

したがって、最小限の失敗の例を見るには、javacなしでソースコードを生成する必要があります。

私の場合、プロジェクトAには別の依存関係があり、X(AはXで定義されたクラスの一部を使用していました)と言います。そのため、AのビルドパスにXを参照プロジェクトとして追加すると、このエラーが発生しました。ただし、参照プロジェクトとしてXを削除し、ライブラリの1つとしてXのjarを含めると、問題は解決しました。

1
user2484130

このページからヒントが得られる場合があります- http://www.zanthan.com/itymbi/archives/000337.html

そのメソッドの本体には、javacが見つけられない微妙なバグがある可能性があります。ここにメソッド全体を投稿しない限り、診断が困難です。

できるだけ多くの変数をfinalとして宣言することから始めることができます。これは、zanthanサイトで言及されているバグをキャッチするはずであり、とにかく良いプラクティスであることがよくあります。

1
Lars Westergren

Java7に移行している場合、またはJava7を使用している場合、一般的にこのエラーが表示されます。上記のエラーに直面し、根本原因を見つけるのに苦労しました。アプリケーションの実行中に"-XX:-UseSplitVerifier" JVM引数を追加することをお勧めします。

1
Ulhas N

クラスパスで同じjarファイルの複数のバージョンを確認してください。

たとえば、クラスパスにopennlp-tools-1.3.0.jarとopennlp-tools-1.5.3.jarがあり、このエラーが発生しました。解決策は、opennlp-tools-1.3.0.jarを削除することでした。

1
demongolem

このエラーの別の理由は、AspectJ <= 1.6.11とJRE> 6の組み合わせです。

詳細については、 Eclipse Bug 353467 および Kieker ticket 307 を参照してください。

これは、JRE 6ですべてが正常に動作し、JRE7に移行すると問題が発生する場合に特に当てはまります。

1

また、mavenで多くのモジュールをインポートしている場合にも発生する可能性があります。まったく同じ名前(同じ修飾名)を持つ2つ以上のクラスがあります。このエラーは、コンパイル時と実行時の解釈の違いが原因です。

1
Toumi

CGLIB <2.2 with JRE> 6でも同様のエラーが発生する可能性があります。 "CGLIB 3.0にアップグレードする必要がありますか?" および Spring SPR-9669 のコメントを参照してください。

これは、JRE 6ですべてが正常に動作し、JRE7に切り替えるだけで問題が解決する場合に特に当てはまります。

1

Java.lang.VerifyErrorは、コンパイルされたバイトコードがAndroidが見つけられないものを参照していることを意味します。このverifyErrorは、両方のデバイスで同じビルドを実行した場合でも、KitKat4.4以前のバージョンではない下位バージョンでのみ発行されます。古いバージョンのjackson 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.+'

次に、Dependencyをcore libraryなしで最新バージョン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'
0
anand krish

使用できないjarファイルを削除して、実行してください。私の仕事はjcommons jarファイルとjcommons.1.0.14 jarファイルを追加したので、jcommonsとその作業を削除します

0
Jat Rahul

ケビンが述べた理由は正しいものの、他の何かに移る前に私は間違いなく以下をチェックします:

  1. クラスパスのcglibsを確認してください。
  2. クラスパスのhibernateバージョンを確認してください。

上記の複数のバージョンまたは競合するバージョンがあると、問題のような予期しない問題が発生する可能性があります。

0
Sandeep Jindal