NoSuchMethodErrorを修正するにはどうすればよいですか?


178

NoSuchMethodErrorJavaプログラムを実行するとエラーが発生します。何が問題で、どうすれば修正できますか?


11
Netbeansの場合:[プロジェクト]タブでプロジェクトを右クリックし、[クリーンとビルド]を使用します。私のためにそれを解決しました。
Heinzlmaen

3
Intellij Ideaでも、リビルドによって問題が解決することがあります
Hawk

1
この資料では、この問題のために非常に有用であるreflectoring.io/nosuchmethod
マイケル・スミス

回答:


228

これ以上の情報がなければ、問題を特定することは困難ですが、根本的な原因は、実行時に使用しているものとは異なる、メソッドが欠落しているクラスの異なるバージョンに対してクラスをコンパイルした可能性が高いことです。

スタックトレースを確認する...ライブラリ内のオブジェクトのメソッドを呼び出すときに例外が表示される場合は、コンパイルおよび実行時にライブラリの別のバージョンを使用している可能性があります。両方のバージョンが正しいバージョンであることを確認してください。

クラスによってインスタンス化されたオブジェクトのメソッドを呼び出すときに例外が表示された場合、あなたが作っし、その後、ビルドプロセスは、障害があると思われます。コンパイル時に、実際に実行しているクラスファイルが更新されていることを確認してください。


3
最近、これらの1つの原因を発見し、Javaサーバーがシャットダウンする前にビルドプロセスがクラスファイルを配置していたことが判明しました。Javaサーバーがいくつかのクラスをロードしていなかったため、これが発生しました。一部のしかしそれはこれらの新しいものを得た、そして新しいコードは古いクラスが持っていなかったメソッドを参照したので...ビンゴ、NoSuchMethodError
vazor

「スタックトレースを見て...」-ええと、ほとんどの場合Caused by、スタックトレースの最後のセクションをチェックして、原因のクラス/ jarを見つけます
KrishPrabakar

108

私はあなたの問題を抱えていました、そしてこれが私がそれを修正した方法です。次の手順は、ライブラリを追加するための有効な方法です。最初の2つのステップは正しく実行しましたが、「。jar」ファイルをファイルシステムから直接Eclipseプロジェクトの「lib」フォルダーにドラッグして、最後のステップを実行していませんでした。さらに、ビルドパスと「lib」フォルダーの両方から以前のバージョンのライブラリを削除する必要がありました。

ステップ1-ビルドパスに.jarを追加する

ここに画像の説明を入力してください

ステップ2-ソースとjavadocsを関連付ける(オプション)

ここに画像の説明を入力してください

ステップ3-実際に.jarファイルを「lib」フォルダーにドラッグします(オプションではありません)

ここに画像の説明を入力してください


75
+1「誰もがあなたがそれを使用する方法を知っていることを期待し、あなたが知らない場合、彼らはあなたの質問に反対票を投じます。」
Vikram 2012年

73

リフレクションの場合はを取得しNoSuchMethodException、非リフレクティブコードの場合はを取得することに注意してくださいNoSuchMethodError。私は一方と他方に直面したときに非常に異なる場所を探しに行く傾向があります。


つまり、クラスでメソッドを取得するためにリフレクションを使用していて、メソッドが見つからない場合は、NoSuchMethodExceptionが発生するということです。しかし、いくつかのライブラリに対してコードをコンパイルしたときに、サーバー上に他のライブラリ(おそらくより新しい可能性が高い)がある場合、NoSuchMethodErrorが返されます。私が間違っていたら訂正してください。
ビクター

正解です。@ Victor
KrishPrabakar

51

JVMパラメータを変更するアクセス権がある場合、詳細出力を追加すると、どのJARファイルからどのクラスがロードされているかを確認できます。

java -verbose:class <other args>

プログラムが実行されると、JVMは次のような標準出力情報にダンプする必要があります。

...

[ファイルから読み込まれたjunit.framework.Assert:/ C:/Program%20Files/junit3.8.2/junit.jar]

...


3
+1ブリリアント!おかげで、この方法を使用して厄介な小さな問題を解決しました。これは、クラスがクラスパスに忍び込んだことを発見するための優れた方法です。
Duncan Jones、

1
+1あなたは私の日を救った!これは、同じ名前の古いクラスをソースに含む1つのライブラリにすぎません。
Andrii Nemchenko

12

これは通常、Javaファイルがクラスファイルよりも新しい場合にのみJavaファイルをコンパイルするApache Antのようなビルドシステムを使用している場合に発生します。メソッドの署名が変更され、クラスが古いバージョンを使用していた場合、正しくコンパイルされない可能性があります。通常の修正は、完全な再構築を行うことです(通常、「ant clean」、「ant」)。

これは、ライブラリの1つのバージョンに対してコンパイルしたが、別のバージョンに対して実行した場合にも発生することがあります。


1
実際、これは、すべてのJava開発フレームワーク(Maven、NetBeans、Apache Ant)を使用しているJavaプログラマーにとって、ここにあるすべての回答からわかるように、より発生する問題のように感じられます。
HoldOffHunger 2016年

8

Mavenまたは別のフレームワークを使用していて、このエラーがほぼランダムに発生する場合は、次のようなクリーンインストールを試してください...

clean install

これは、オブジェクトを作成し、そのオブジェクトにメソッドがあることがわかっている場合に特に機能します。私のために働いた。


これは、Gradleビルドにも当てはまります。
ジョナサンランドラム

4

これは、反射を使用した結果である場合もあります。クラスを反映し、名前でメソッドを抽出するコード(例:with Class.getDeclaredMethod("someMethodName", .....))がある場合、リファクタリング中など、そのメソッド名が変更されるたびに、リフレクションメソッドのパラメーターを更新して、新しいメソッドシグネチャ、またはgetDeclaredMethod呼び出しはをスローしNoSuchMethodExceptionます。

これが理由である場合、スタックトレースはリフレクションメソッドが呼び出されたポイントを示す必要があり、実際のメソッドシグネチャと一致するようにパラメーターを更新する必要があるだけです。

私の経験では、プライベートメソッド/フィールドをユニットテストし、TestUtilitiesクラスを使用してテスト検証のためにフィールドを抽出するときに、これが時々発生します。(通常、単体テストを考慮して設計されていないレガシーコードを使用します。)


3

ウェブアプリを作成している場合は、コンテナーのグローバルライブラリディレクトリとアプリに、jarのバージョンが競合していないことを確認してください。クラスローダーでどのjarが使用されているかは、必ずしもわかっているとは限りません。

例えば

  • tomcat / common / lib
  • mywebapp / WEB-INF / lib

2

これらの問題は、同じ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です)。


2

これは、それぞれのメソッドがクラスに存在しないことを意味します。

  1. jarを使用している場合は、逆コンパイルして、jarのそれぞれのバージョンに適切なクラスがあるかどうかを確認します。
  2. ソースから適切なクラスをコンパイルしたかどうかを確認します。

2

私にとっては、関数の引数の型をObject aからString aに変更したために起こりました。私はそれをクリーンで解決して再構築できました


2

私はEclipseを再起動してアプリケーションを実行することでこのエラーを解決しました。私のケースの理由は、プロジェクトまたはEclipseを閉じずにソースファイルを置き換えるためです。これにより、使用していたクラスのバージョンが異なりました。


2

この方法を試してください。プロジェクトディレクトリ(もちろん、すべてのサブディレクトリ)の下にあるすべての.classファイルを削除します。再構築。

場合によってはmvn clean(mavenを使用している場合)、によって手動で作成された.classファイルがクリーンアップされないことがありますjavac。そして、それらの古いファイルがにつながる、古い署名が含まれていますNoSuchMethodError


2

既存の回答に追加するだけです。私は日食のTomcatでこの問題に直面していました。1つのクラスを変更して、次の手順を実行しました。

  1. eclpiseでプロジェクトをクリーンアップしてビルドしました

  2. mvnクリーンインストール

  3. Tomcatを再起動しました

それでも私は同じエラーに直面していました。次に、tomcatをクリーンアップし、tomcatの作業ディレクトリクリーンアップしてサーバーを再起動したところ、問題は解決しました。これが誰かを助けることを願っています


1

元の質問に答える。ここの Javaドキュメントによると:

"NoSuchMethodError"アプリケーションがクラス(静的またはインスタンス)の指定されたメソッドを呼び出そうとして、そのクラスにそのメソッドの定義がなくなった場合にスローされます。

通常、このエラーはコンパイラーによってキャッチされます。このエラーは、クラスの定義が互換性なく変更された場合にのみ実行時に発生します。

  1. 実行時に発生する場合は、メソッドを含むクラスがクラスパスにあることを確認してください。
  2. JARの新しいバージョンを追加したかどうか、およびメソッドに互換性があるかどうかを確認してください。

1

Junitテストファイルの名前を変更して、Eclipseでこの問題を修正しました。
私のEclipseワークスペースには、AppプロジェクトとTestプロジェクトがあります。
テストプロジェクトには、ビルドパス上の必須プロジェクトとしてAppプロジェクトがあります。

NoSuchMethodErrorの取得を開始しました。
次に、TestプロジェクトのクラスがAppプロジェクトのクラスと同じ名前であることに気付きました。

App/  
  src/
     com.example/  
       Projection.java
Test/  
  src/
     com.example/
       Projection.java

テストの名前を「ProjectionTest.java」に変更した後、例外はなくなりました。


同様の問題がありました。同じ完全な正規名を持つ依存関係クラスがありました。例外の名前を変更した後、消えました。
moralejaSinCuentoNiProverbio

1

私は同じエラーがありました:

  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>

不要なバージョンの依存関係はプロジェクトから除外されます。


1

私の場合、マルチモジュールプロジェクトがあり、シナリオはcom.xyz.TestClassモジュール内にAあり、モジュール内BとモジュールAはモジュールに依存していましたB。したがって、アセンブリjarを作成しているときに、呼び出されたメソッドがない場合、クラスの1つのバージョンのみが保持されたと思いNoSuchMethodErrorます。実行時例外が発生しましたが、コンパイルは問題ありませんでした。

関連:https : //reflectoring.io/nosuchmethod/


0

アプリケーションでメソッドシグネチャを変更しているときに、同様の問題に遭遇しました。プロジェクトをクリーンアップして再ビルドすると、「NoSuchMethodError」が解決されました。


0

上記の答えは非常によく説明しています.. 1つのことを追加するだけEclipseを使用している場合はctrl + shift + Tを使用し、クラスのパッケージ構造を入力します(例:gateway.smpp.PDUEventListener)、それが存在するすべてのjar /プロジェクトが見つかります。クラスパスから不要なjarを削除するか、クラスパスに上記を追加してください。今では正しいものを拾います。


0

私は同様の問題に遭遇しました。

Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I

最後に、根本的な原因が変数のデータ型の変更であることを特定しました。

  1. Employee.java- >変数(入ってEmpId)そのデータタイプに変更されましたintString
  2. ReportGeneration.java->ゲッターを使用して値を取得しますgetEmpId()

変更されたクラスのみを含めることにより、jarを再バンドルすることになっています。変更はなかったので、JarファイルReportGeneration.javaのみを含めましEmployee.classた。ReportGeneration.class問題を解決するには、ファイルをjarファイルに含める必要がありました。


0

同じ問題がありました。これは、クラスにあいまいさがある場合にも発生します。私のプログラムは、同じ場所/クラスパスにある2つのJARファイルにあるメソッドを呼び出そうとしました。1つのJARファイルを削除するか、1つのJARファイルのみが使用されるようにコードを実行します。同じJAR、または同じクラスを含む同じJARの異なるバージョンを使用していないことを確認してください。

DISP_E_EXCEPTION [ステップ] [] [Z-JAVA-105 Java例外java.lang.NoSuchMethodError(com.example.yourmethod)]



0

私もこのエラーに遭遇しました。

私の問題は、メソッドのシグネチャを次のように変更したことです

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をロードした後、そのようなメソッドは見つかりません。削除され、変更されていないように見えるため、名前付きエラーになります。

お役に立てれば。


0

私の場合の問題は、ビルドパスに同じライブラリの2つのバージョンがあることでした。古いバージョンのライブラリには機能がなく、新しいバージョンには機能がありました。


0

Intelijを使用するGradleプロジェクトでも同様の問題がありました。.gradle(下のスクリーンショットを参照)パッケージを削除してプロジェクトを再ビルドすることで解決しました。 .gradleパッケージ


0

NoSuchMethodError:私はこの問題を修正するために数時間を費やしましたが、最後にパッケージ名の名前を変更して修正し、クリーンしてビルドします...機能しない場合は、まずクリーンビルドを試してください。クラス名またはパッケージ名の名前を変更してビルドをクリーンアップしてください。修正する必要があります。幸運を。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.