NoSuchMethodError
Javaプログラムを実行するとエラーが発生します。何が問題で、どうすれば修正できますか?
NoSuchMethodError
Javaプログラムを実行するとエラーが発生します。何が問題で、どうすれば修正できますか?
回答:
これ以上の情報がなければ、問題を特定することは困難ですが、根本的な原因は、実行時に使用しているものとは異なる、メソッドが欠落しているクラスの異なるバージョンに対してクラスをコンパイルした可能性が高いことです。
スタックトレースを確認する...ライブラリ内のオブジェクトのメソッドを呼び出すときに例外が表示される場合は、コンパイルおよび実行時にライブラリの別のバージョンを使用している可能性があります。両方のバージョンが正しいバージョンであることを確認してください。
クラスによってインスタンス化されたオブジェクトのメソッドを呼び出すときに例外が表示された場合、あなたが作っし、その後、ビルドプロセスは、障害があると思われます。コンパイル時に、実際に実行しているクラスファイルが更新されていることを確認してください。
Caused by
、スタックトレースの最後のセクションをチェックして、原因のクラス/ jarを見つけます
私はあなたの問題を抱えていました、そしてこれが私がそれを修正した方法です。次の手順は、ライブラリを追加するための有効な方法です。最初の2つのステップは正しく実行しましたが、「。jar」ファイルをファイルシステムから直接Eclipseプロジェクトの「lib」フォルダーにドラッグして、最後のステップを実行していませんでした。さらに、ビルドパスと「lib」フォルダーの両方から以前のバージョンのライブラリを削除する必要がありました。
リフレクションの場合はを取得しNoSuchMethodException
、非リフレクティブコードの場合はを取得することに注意してくださいNoSuchMethodError
。私は一方と他方に直面したときに非常に異なる場所を探しに行く傾向があります。
JVMパラメータを変更するアクセス権がある場合、詳細出力を追加すると、どのJARファイルからどのクラスがロードされているかを確認できます。
java -verbose:class <other args>
プログラムが実行されると、JVMは次のような標準出力情報にダンプする必要があります。
...
[ファイルから読み込まれたjunit.framework.Assert:/ C:/Program%20Files/junit3.8.2/junit.jar]
...
これは通常、Javaファイルがクラスファイルよりも新しい場合にのみJavaファイルをコンパイルするApache Antのようなビルドシステムを使用している場合に発生します。メソッドの署名が変更され、クラスが古いバージョンを使用していた場合、正しくコンパイルされない可能性があります。通常の修正は、完全な再構築を行うことです(通常、「ant clean」、「ant」)。
これは、ライブラリの1つのバージョンに対してコンパイルしたが、別のバージョンに対して実行した場合にも発生することがあります。
Mavenまたは別のフレームワークを使用していて、このエラーがほぼランダムに発生する場合は、次のようなクリーンインストールを試してください...
clean install
これは、オブジェクトを作成し、そのオブジェクトにメソッドがあることがわかっている場合に特に機能します。私のために働いた。
これは、反射を使用した結果である場合もあります。クラスを反映し、名前でメソッドを抽出するコード(例:with Class.getDeclaredMethod("someMethodName", .....)
)がある場合、リファクタリング中など、そのメソッド名が変更されるたびに、リフレクションメソッドのパラメーターを更新して、新しいメソッドシグネチャ、またはgetDeclaredMethod
呼び出しはをスローしNoSuchMethodException
ます。
これが理由である場合、スタックトレースはリフレクションメソッドが呼び出されたポイントを示す必要があり、実際のメソッドシグネチャと一致するようにパラメーターを更新する必要があるだけです。
私の経験では、プライベートメソッド/フィールドをユニットテストし、TestUtilities
クラスを使用してテスト検証のためにフィールドを抽出するときに、これが時々発生します。(通常、単体テストを考慮して設計されていないレガシーコードを使用します。)
ウェブアプリを作成している場合は、コンテナーのグローバルライブラリディレクトリとアプリに、jarのバージョンが競合していないことを確認してください。クラスローダーでどのjarが使用されているかは、必ずしもわかっているとは限りません。
例えば
これらの問題は、同じ2つのクラスで同じオブジェクトを使用することによって発生します。使用されるオブジェクトに新しいメソッドが含まれていない新しいオブジェクトクラスに含まれる新しいメソッドが追加されました。
例:
filenotnull=/DayMoreConfig.conf
16-07-2015 05:02:10:ussdgw-1: Open TCP/IP connection to SMSC: 10.149.96.66 at 2775
16-07-2015 05:02:10:ussdgw-1: Bind request: (bindreq: (pdu: 0 9 0 [1]) 900 900 GEN 52 (addrrang: 0 0 2000) )
Exception in thread "main" java.lang.NoSuchMethodError: gateway.smpp.PDUEventListener.<init>(Lgateway/smpp/USSDClient;)V
at gateway.smpp.USSDClient.bind(USSDClient.java:139)
at gateway.USSDGW.initSmppConnection(USSDGW.java:274)
at gateway.USSDGW.<init>(USSDGW.java:184)
at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40)
-bash-3.00$
これらの問題は、付随する02の同様のクラスが原因で発生します(srcに1つ、ここではjarファイルに1つはgateway.jarです)。
元の質問に答える。ここの Javaドキュメントによると:
"NoSuchMethodError"アプリケーションがクラス(静的またはインスタンス)の指定されたメソッドを呼び出そうとして、そのクラスにそのメソッドの定義がなくなった場合にスローされます。
通常、このエラーはコンパイラーによってキャッチされます。このエラーは、クラスの定義が互換性なく変更された場合にのみ実行時に発生します。
Junitテストファイルの名前を変更して、Eclipseでこの問題を修正しました。
私のEclipseワークスペースには、AppプロジェクトとTestプロジェクトがあります。
テストプロジェクトには、ビルドパス上の必須プロジェクトとしてAppプロジェクトがあります。
NoSuchMethodErrorの取得を開始しました。
次に、TestプロジェクトのクラスがAppプロジェクトのクラスと同じ名前であることに気付きました。
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
テストの名前を「ProjectionTest.java」に変更した後、例外はなくなりました。
私は同じエラーがありました:
Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonGenerator.writeStartObject(Ljava/lang/Object;)V
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:151)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)
それを解決するために、まず、モジュール依存図(click in your POM the combination -> Ctrl+Alt+Shift+U
またはright click in your POM -> Maven -> Show dependencies
)をチェックして、ライブラリ(Intelij IDEA)間の競合が正確にどこにあるかを理解しました。私の特定のケースでは、ジャクソン依存関係の異なるバージョンがありました。
1)それで、私はプロジェクトのPOMに直接、最も高いバージョンを明示的に追加しました-これらの2つの2.8.7。
プロパティ:
<jackson.version>2.8.7</jackson.version>
そして依存として:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2)しかし、依存関係の除外を使用して解決することもできます。
以下の例と同じ原理で:
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
不要なバージョンの依存関係はプロジェクトから除外されます。
私の場合、マルチモジュールプロジェクトがあり、シナリオはcom.xyz.TestClass
モジュール内にA
あり、モジュール内B
とモジュールA
はモジュールに依存していましたB
。したがって、アセンブリjarを作成しているときに、呼び出されたメソッドがない場合、クラスの1つのバージョンのみが保持されたと思いNoSuchMethodError
ます。実行時例外が発生しましたが、コンパイルは問題ありませんでした。
私は同様の問題に遭遇しました。
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
最後に、根本的な原因が変数のデータ型の変更であることを特定しました。
Employee.java
- >変数(入ってEmpId
)そのデータタイプに変更されましたint
へString
。ReportGeneration.java
->ゲッターを使用して値を取得しますgetEmpId()
。変更されたクラスのみを含めることにより、jarを再バンドルすることになっています。変更はなかったので、JarファイルReportGeneration.java
のみを含めましEmployee.class
た。ReportGeneration.class
問題を解決するには、ファイルをjarファイルに含める必要がありました。
同じ問題がありました。これは、クラスにあいまいさがある場合にも発生します。私のプログラムは、同じ場所/クラスパスにある2つのJARファイルにあるメソッドを呼び出そうとしました。1つのJARファイルを削除するか、1つのJARファイルのみが使用されるようにコードを実行します。同じJAR、または同じクラスを含む同じJARの異なるバージョンを使用していないことを確認してください。
DISP_E_EXCEPTION [ステップ] [] [Z-JAVA-105 Java例外java.lang.NoSuchMethodError(com.example.yourmethod)]
ほとんどの場合、java.lang.NoSuchMethodErrorはコンパイラーによってキャッチされますが、実行時に発生することもあります。このエラーが実行時に発生する場合、唯一の理由は、互換性を失わせたクラス構造の変更である可能性があります。
最良の説明:https : //www.journaldev.com/14538/java-lang-nosuchmethoderror
私もこのエラーに遭遇しました。
私の問題は、メソッドのシグネチャを次のように変更したことです
void invest(Currency money){...}
に
void invest(Euro money){...}
このメソッドは、次のようなコンテキストから呼び出されました
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
資本は通貨とユーロの両方であるので、コンパイラーは警告/エラーに関して静かでした。
この問題は、メソッドが定義されたクラス-Bankのみをコンパイルしたが、メソッドの呼び出し元のクラス(main()メソッドを含む)はコンパイルしなかったために発生しました。
ほとんどの場合、プロジェクトは手動で再ビルドされるか、1つの変更されたクラスをコンパイルするだけでなく、ビルドアクションが自動的にトリガーされるため、この問題はあまり頻繁に発生する可能性がある問題ではありません。
私のユースケースは、修正プログラムとして使用される.jarファイルを生成し、これは変更されていないため、App.classを含まないというものでした。最初の引数の基底クラスの継承を継承したので、これを含めないのは理にかなっています。
重要なのは、クラスをコンパイルすると、結果のバイトコードが一種のstaticになる、つまり、ハード参照になるということです。
(javapツールで生成された)元の逆アセンブルされたバイトコードは次のようになります。
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
ClassLoaderが新しくコンパイルされたBank.classをロードした後、そのようなメソッドは見つかりません。削除され、変更されていないように見えるため、名前付きエラーになります。
お役に立てれば。
Intelijを使用するGradleプロジェクトでも同様の問題がありました。.gradle(下のスクリーンショットを参照)パッケージを削除してプロジェクトを再ビルドすることで解決しました。 .gradleパッケージ
NoSuchMethodError:私はこの問題を修正するために数時間を費やしましたが、最後にパッケージ名の名前を変更して修正し、クリーンしてビルドします...機能しない場合は、まずクリーンビルドを試してください。クラス名またはパッケージ名の名前を変更してビルドをクリーンアップしてください。修正する必要があります。幸運を。