web-dev-qa-db-ja.com

Java "NoSuchMethodError"

私は得ています:

NoSuchMethodError: com.foo.SomeService.doSmth()Z

このことを正しく理解していますか'Z'は、doSmth()メソッドの戻り値の型がブール値であることを意味しますか? trueの場合、このメソッドはいくつかのコレクションを返すため、この種のメソッドは実際には存在しません。しかし一方で、このメソッドを呼び出す場合、その戻り値を変数に割り当てていません。私はこのメソッドを次のように呼び出すだけです:

service.doSmth();

このエラーが発生する理由は何ですか?必要なすべてのJARファイルが存在し、このクラスの他のすべてのメソッドが存在するようです。

26
vrm

コンパイル中はクラスパスにメソッドが存在するように見えますが、アプリケーションの実行中はそうではありません。

戻り値の型は問題ではないと思います。もしそうなら、それはコンパイルされません。メソッドの呼び出しがあいまいで、2つのメソッドが戻り値の型のみが異なる場合、コンパイラーはエラーをスローします。

24
amorfis

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

つまり、実行時のクラス/ jarファイルは、コンパイル時に使用したものとは異なります。

18
Bozho

これはおそらく、コンパイル時のクラスパスと実行時のクラスパスの違いです。

これが起こっているようです:

  • コードは、ブール値を返すdoSmth()メソッドを定義するクラスパスでコンパイルされます。バイトコードはdoSmth()Zメソッドを参照します。
  • 実行時に、doSmth()Zメソッドが見つかりません。代わりに、コレクションを返すメソッドが見つかります。

この問題を修正するには、(コンパイル時の)クラスパスを確認してください。

17
Vivien Barousse

現在の返信では、なぜ失敗しているのかがわかります。通常、問題を修正する方法を知っているとさらに便利です。言及したように、問題は通常、プログラムをビルドしたことですが、実行またはエクスポートするときに、ライブラリが含まれていません。だから解決策は...

実行している場合は、実行構成を確認します。「実行」タブを選択します->実行構成->実行している構成を選択します->「クラスパス」タブを確認します->必要なライブラリがあることを確認します

エクスポートする場合(たとえば、warファイル)、プロジェクトの選択->プロパティの選択->デプロイメントアセンブリの選択->追加を押す->選択Javaビルドパスエントリ->ライブラリを選択エクスポートしたファイル(たとえば、warファイル)に含めたい

どちらの場合も、参照しているライブラリが含まれていることを確認してください。

このエラーの他のよくある問題は、正しいタイプのパラメーターや可視性ではありませんが、コンパイラーは実行前にエラーを検出します。この場合、ドキュメントをチェックして関数とパッケージの可視性を一致させ、ライブラリがプロジェクトのプロパティのJavaビルドパスにあることを確認してください。

4
Capagris

おそらく誰かを助けることができるかもしれませんが、この例外は、まったく同じシグネチャを持つが同じパブリックメソッドを持たない、異なるjarファイル内の2つのクラスがクラスパス上にある場合にも発生する可能性があります。

例えば:

  • ファイルmylibrary1.jarには、メソッドdoSmth()を持つクラスcom.mypackage.mysubpackage.MyClassがあります。

  • ファイルmylibrary2.jarには、クラスcom.mypackage.mysubpackage.MyClass withoutメソッドdoSmth()があります。

クラスを検索するとき、クラスローダーはパスの優先順位に応じて最初にmylibrary2.jarを見つけることができますが、そのクラスのメソッドを見つけることができません。

2つの異なるファイルに同じパッケージ+クラスがないことを確認してください。

3
dgisbert

EclipseでSVNから更新した後、複数のリンクされたプロジェクトでいくつかの実験的な変更をテストしているときに、この問題が発生していることに気付きました。

具体的には、SVNからすべてのプロジェクトを更新し、.classpathファイルを手動で編集するのではなく、元に戻しました。

次に、リンクされたプロジェクトをパスに再度追加しましたが、関連するjarを削除するのを忘れていました。このようにして問題が発生しました。

したがって、コンパイラがプロジェクトファイルを使用している間、ランタイムはjarファイルを使用しているようです。

2
ekangas

これが発生する可能性があり、見つけるのが難しい別の方法:

外部jarのメソッドのシグネチャがIDEでエラーが見つからないような方法で変更された場合、それは呼び出し方法との互換性があるため、クラスは再コンパイルされない可能性があります。

ビルドでファイルの変更をチェックしてから再コンパイルする場合、ビルドプロセス中にクラスが再コンパイルされない可能性があります。

したがって、実行すると、この問題が発生する可能性があります。あなたは新しいjarを持っていますが、あなた自身のコードは古いものを期待していますが、文句を言うことはありません。

それをより困難にするために、そのようなケースを処理できるかどうかは、jvmに依存します。したがって、最悪の場合、テストサーバーでは実行されますが、ライブマシンでは実行されません。

0
Christian