webentwicklung-frage-antwort-db.com.de

Java "NoSuchMethodError"

Ich erhalte: 

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

Verstehe ich richtig, dass dieser 'Z' bedeutet, dass der Rückgabetyp der Methode doSmth () boolean ist? Wenn ja, existiert diese Methode wirklich nicht, da diese Methode eine Collection zurückgibt. Wenn ich diese Methode jedoch aufrufe, ordne ich ihren Rückgabewert keiner Variablen zu. Ich nenne diese Methode einfach so:

service.doSmth();

Irgendwelche Ideen, warum dieser Fehler auftritt? Alle erforderlichen JAR-Dateien sind vorhanden und alle anderen Methoden dieser Klasse scheinen vorhanden zu sein. 

25
vrm

Sieht so aus, als ob die Methode während des Kompilierens im Klassenpfad vorhanden ist, aber nicht während der Ausführung Ihrer Anwendung.

Ich glaube nicht, dass der Rückgabetyp ein Problem ist. Wenn ja, würde es nicht kompilieren. Der Compiler gibt einen Fehler aus, wenn der Methodenaufruf mehrdeutig ist und sich zwei Methoden nur durch den Rückgabetyp unterscheiden.

24
amorfis

Normalerweise wird dieser Fehler vom Compiler abgefangen. Dieser Fehler kann nur zur Laufzeit auftreten, wenn sich die Definition einer Klasse inkompatibel geändert hat.

Kurz gesagt, eine Klasse/JAR-Datei zur Laufzeit ist nicht die gleiche, die Sie zur Kompilierzeit verwendet haben.

18
Bozho

Dies ist wahrscheinlich ein Unterschied zwischen Ihrem Klassenpfad zur Kompilierungszeit und Ihrem Klassenpfad zur Laufzeit.

Folgendes scheint zu sein:

  • Der Code wird mit einem Klassenpfad kompiliert, der die doSmth()-Methode definiert, die einen Boolean zurückgibt. Der Bytecode bezieht sich auf die doSmth()Z-Methode.
  • Zur Laufzeit wird die doSmth()Z-Methode nicht gefunden. Stattdessen wird eine Methode gefunden, die eine Collection zurückgibt.

Um dieses Problem zu beheben, überprüfen Sie den Klassenpfad (Kompilierzeit).

16
Vivien Barousse

In der aktuellen Antwort erfahren Sie nur, warum dies nicht funktioniert. Normalerweise ist es noch schöner zu wissen, wie man Probleme löst. Wie bereits erwähnt, besteht das Problem in der Regel darin, dass Sie Ihr Programm erstellt haben, aber beim Ausführen oder Exportieren der Bibliothek ist die Bibliothek nicht enthalten. Die Lösung ist also ...

Wenn Sie aktiv sind, überprüfen Sie die Ausführungskonfiguration. Wählen Sie die Registerkarte Ausführen -> Konfigurationen ausführen -> Wählen Sie die Konfiguration aus, die Sie ausführen -> Überprüfen Sie die Registerkarte Classpath -> Stellen Sie sicher, dass die benötigten Bibliotheken vorhanden sind

Wenn Sie exportieren (z. B. eine War-Datei), gehen Sie wie folgt vor: Projekt auswählen -> Eigenschaften auswählen -> Bereitstellungsassembly auswählen -> Klicken Sie auf Hinzufügen -> Java-Build-Pfadeinträge auswählen -> Wählen Sie die Bibliotheken aus, in die aufgenommen werden soll Ihre exportierte Datei (zum Beispiel eine Kriegsdatei)

Stellen Sie in beiden Fällen sicher, dass die Bibliothek, auf die Sie sich beziehen, enthalten ist.

Andere häufige Probleme für diesen Fehler sind nicht die richtigen Parameter oder die Sichtbarkeit. Der Compiler erkennt den Fehler jedoch vor der Ausführung. Überprüfen Sie in diesem Fall einfach die Dokumentation, um die Funktions- und Paketsichtbarkeit zu überprüfen, und stellen Sie sicher, dass sich die Bibliothek im Java Build Path in Ihren Projekteigenschaften befindet.

4
Capagris

Vielleicht kann noch jemandem helfen, aber diese Ausnahme kann auch auftreten, wenn auf dem Klassenpfad zwei Klassen in verschiedenen JAR-Dateien vorhanden sind, die die gleiche Signatur haben, jedoch nicht die gleichen öffentlichen Methoden haben.

Zum Beispiel:

  • In der Datei mylibrary1.jar haben Sie die Klasse com.mypackage.mysubpackage.MyClass mit der Methode doSmth ().

  • In der Datei mylibrary2.jar befindet sich die Klasse com.mypackage.mysubpackage.MyClass ohne Methode doSmth ().

Beim Durchsuchen der Klasse findet der Classloader möglicherweise die erste Datei mylibrary2.jar in Abhängigkeit von der Pfadpriorität, kann jedoch die Methode in dieser Klasse nicht finden.

Stellen Sie sicher, dass Sie nicht das gleiche Paket + Klasse für zwei verschiedene Dateien haben.

3
dgisbert

Ich habe dieses Problem beim Testen einiger experimenteller Änderungen in mehreren verknüpften Projekten festgestellt, nachdem ich sie in SVL in Eclipse aktualisiert hatte. 

Insbesondere habe ich alle Projekte aus dem SVN aktualisiert und die .classpath-Datei zurückgesetzt, anstatt sie manuell zu bearbeiten, um die Dinge einfach zu halten. 

Dann fügte ich die verknüpften Projekte wieder dem Pfad hinzu, vergaß jedoch, die zugehörigen Gläser zu entfernen. So entstand das Problem für mich. 

Anscheinend hat die Laufzeit die JAR-Datei verwendet, während der Compiler die Projektdateien verwendet hat.

2
ekangas

Auf andere Weise kann dies passieren und ist schwer zu finden:

Wenn sich eine Signatur einer Methode in einem externen Jar so ändert, dass in der IDE kein Fehler gefunden wird, da sie immer noch mit der Art und Weise kompatibel ist, wie Sie sie nennen, wird die Klasse möglicherweise nicht erneut kompiliert.

Wenn Ihr Build die Dateien auf Änderungen überprüft und sie erst dann neu kompiliert, wird die Klasse während des Buildvorgangs möglicherweise nicht erneut kompiliert.

Wenn Sie es ausführen, kann dies zu diesem Problem führen. Obwohl Sie das neue Glas haben, erwartet Ihr eigener Code immer noch den alten, beschwert sich aber nie.

Um es schwieriger zu machen, hängt es von der jvm ab, ob sie mit solchen Fällen umgehen kann. Im schlimmsten Fall läuft es also auf dem Testserver, aber nicht auf dem Live-Rechner.

0
Christian