私は次の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つのサーブレットのみが故障しています。どこを探すべきかは、役に立つでしょう。
Java.lang.VerifyError
は、実行時に使用しているものとは異なるライブラリに対してコンパイルした場合に結果になる可能性があります。
たとえば、Xerces 1に対してコンパイルされたプログラムを実行しようとしたときに、Xerces 2がクラスパスに見つかりました。必要なクラス(org.Apache.*
名前空間内)は実行時に見つかったため、ClassNotFoundException
はnotの結果でした。クラスとメソッドに変更が加えられたため、実行時に見つかったメソッドシグネチャがコンパイル時に存在したものと一致しませんでした。
通常、コンパイラはメソッドシグネチャが一致しない問題にフラグを立てます。 JVMは、クラスがロードされるとバイトコードを再度検証し、バイトコードが許可されてはならないことを実行しようとするとVerifyError
をスローします。 String
を返すメソッドを呼び出し、その戻り値をList
を保持するフィールドに格納します。
Java.lang.VerifyError
は最悪です。
メソッドのバイトコードサイズが64kbの制限を超えると、このエラーが発生します。しかし、おそらくあなたはそれに気づいたでしょう。
このクラスがアプリケーションの別のクラスパス、おそらく別のjarに存在しないことを100%確信していますか?
また、スタックトレースから、ソースファイルの文字エンコーディング(utf-8
?)は正しいですか?
ケビン・パンコが言ったように、それは主に図書館の変更によるものです。そのため、場合によっては、プロジェクト(ディレクトリ)の「クリーン」とそれに続くビルドがトリックを行います。
ここで説明するように、ライブラリをインポートするプロジェクトを作成することで、Androidでこのエラーを修正しました http://developer.Android.com/tools/projects/projects-Eclipse.html#SettingUpLibraryProject
以前は、プロジェクトを参照するだけで(ライブラリにしない)、この奇妙なVerifyErrorが発生していました。
それが誰かを助けることを願っています。
VerifyErrorは、クラスファイルに構文的に正しいバイトコードが含まれていますが、何らかのセマンティック制限に違反していることを意味します。メソッドの境界を越えるジャンプターゲット。
基本的に、VerifyErrorが発生するのは、コンパイラのバグがある場合、またはクラスファイルが他の何らかの方法で破損した場合(たとえば、障害のあるRAMまたはHDの障害)のみです。
別のJDKバージョンと別のマシンでコンパイルしてみてください。
あなたが試みるかもしれないことの1つは、ロード時にバイトコードを検証する-Xverify:all
を使用することです。
私の場合、Androidプロジェクトは、Java 7用にコンパイルされた別のJavaプロジェクトに依存しています。Java.lang.VerifyError
は、Javaプロジェクトの
後で、これはDalvikの問題であることがわかりました。 https://groups.google.com/forum/?fromgroups#!topic/Android-developers/sKsMTZ42pwE
Pack200がクラスファイルをマングルしているため、この問題が発生していました。少し検索すると、これが Javaバグ になりました。基本的に、--effort=4
を設定すると、問題はなくなりました。
Java 1.5.0_17を使用します(ただし、Java 1.5のすべてのバリアントで発生しましたが、試しました)。
これは、OracleのJDKに対してコンパイルされたライブラリをロードしようとしたときに、Androidで発生する可能性があります。
問題があります Ning Async HTTPクライアントの場合。
私は同様の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()
メソッド呼び出しの近くでエラーが表示されていました。
エラーを生成する最小限の例
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コンパイラーが暗黙的にreturn
をvoid
メソッドに追加するため、通常Javaで発生することはありません。これが、return
をmain
メソッドに追加する必要がない理由です。これは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を含めると、問題は解決しました。
このページからヒントが得られる場合があります- http://www.zanthan.com/itymbi/archives/000337.html
そのメソッドの本体には、javacが見つけられない微妙なバグがある可能性があります。ここにメソッド全体を投稿しない限り、診断が困難です。
できるだけ多くの変数をfinalとして宣言することから始めることができます。これは、zanthanサイトで言及されているバグをキャッチするはずであり、とにかく良いプラクティスであることがよくあります。
Java7に移行している場合、またはJava7を使用している場合、一般的にこのエラーが表示されます。上記のエラーに直面し、根本原因を見つけるのに苦労しました。アプリケーションの実行中に"-XX:-UseSplitVerifier" JVM引数を追加することをお勧めします。
クラスパスで同じjarファイルの複数のバージョンを確認してください。
たとえば、クラスパスにopennlp-tools-1.3.0.jarとopennlp-tools-1.5.3.jarがあり、このエラーが発生しました。解決策は、opennlp-tools-1.3.0.jarを削除することでした。
このエラーの別の理由は、AspectJ <= 1.6.11とJRE> 6の組み合わせです。
詳細については、 Eclipse Bug 353467 および Kieker ticket 307 を参照してください。
これは、JRE 6ですべてが正常に動作し、JRE7に移行すると問題が発生する場合に特に当てはまります。
また、mavenで多くのモジュールをインポートしている場合にも発生する可能性があります。まったく同じ名前(同じ修飾名)を持つ2つ以上のクラスがあります。このエラーは、コンパイル時と実行時の解釈の違いが原因です。
CGLIB <2.2 with JRE> 6でも同様のエラーが発生する可能性があります。 "CGLIB 3.0にアップグレードする必要がありますか?" および Spring SPR-9669 のコメントを参照してください。
これは、JRE 6ですべてが正常に動作し、JRE7に切り替えるだけで問題が解決する場合に特に当てはまります。
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'
使用できないjarファイルを削除して、実行してください。私の仕事はjcommons jarファイルとjcommons.1.0.14 jarファイルを追加したので、jcommonsとその作業を削除します
ケビンが述べた理由は正しいものの、他の何かに移る前に私は間違いなく以下をチェックします:
cglibs
を確認してください。hibernate
バージョンを確認してください。上記の複数のバージョンまたは競合するバージョンがあると、問題のような予期しない問題が発生する可能性があります。