NoSuchMethodError
Beim Ausführen meines Java-Programms wird eine Fehlermeldung angezeigt. Was ist los und wie behebe ich das?
NoSuchMethodError
Beim Ausführen meines Java-Programms wird eine Fehlermeldung angezeigt. Was ist los und wie behebe ich das?
Antworten:
Ohne weitere Informationen ist es schwierig, das Problem genau zu bestimmen. Die Hauptursache ist jedoch, dass Sie höchstwahrscheinlich eine Klasse für eine andere Version der Klasse kompiliert haben, bei der eine Methode fehlt, als die, die Sie beim Ausführen verwenden.
Sehen Sie sich den Stack-Trace an ... Wenn die Ausnahme beim Aufrufen einer Methode für ein Objekt in einer Bibliothek auftritt, verwenden Sie beim Kompilieren und Ausführen höchstwahrscheinlich separate Versionen der Bibliothek. Stellen Sie sicher, dass Sie an beiden Stellen die richtige Version haben.
Wenn die Ausnahme beim Aufrufen einer Methode für Objekte auftritt, die von von Ihnen erstellten Klassen instanziiert wurden , scheint Ihr Erstellungsprozess fehlerhaft zu sein. Stellen Sie sicher, dass die Klassendateien, die Sie tatsächlich ausführen, beim Kompilieren aktualisiert werden.
Ich hatte Ihr Problem und so habe ich es behoben. Mit den folgenden Schritten können Sie eine Bibliothek hinzufügen. Ich hatte die ersten beiden Schritte richtig gemacht, aber den letzten nicht, indem ich die Datei ".jar" direkt aus dem Dateisystem in den Ordner "lib" in meinem Eclipse-Projekt gezogen hatte. Außerdem musste ich die vorherige Version der Bibliothek sowohl aus dem Erstellungspfad als auch aus dem Ordner "lib" entfernen.
Beachten Sie, dass Sie im Fall von Reflexion einen erhalten NoSuchMethodException
, während Sie bei nicht reflektierendem Code einen erhalten NoSuchMethodError
. Ich neige dazu, an sehr unterschiedlichen Orten zu suchen, wenn ich mit einem gegen den anderen konfrontiert werde.
Wenn Sie Zugriff auf die Änderung der JVM-Parameter haben, sollten Sie durch Hinzufügen einer ausführlichen Ausgabe sehen können, welche Klassen aus welchen JAR-Dateien geladen werden.
java -verbose:class <other args>
Wenn Ihr Programm ausgeführt wird, sollte die JVM Dump-to-Standard-Out-Informationen wie:
...
[Junit.framework.Assert aus Datei geladen: / C: /Program%20Files/junit3.8.2/junit.jar]
...
Dies wird normalerweise verursacht, wenn ein Build-System wie verwendet wird Apache Ant verwendet wird , das Java-Dateien nur kompiliert, wenn die Java-Datei neuer als die Klassendatei ist. Wenn Änderungen an einer Methodensignatur und Klassen die alte Version verwenden, werden die Dinge möglicherweise nicht korrekt kompiliert. Die übliche Lösung besteht darin, einen vollständigen Neuaufbau durchzuführen (normalerweise "Ameisen sauber", dann "Ameise").
Manchmal kann dies auch beim Kompilieren mit einer Version einer Bibliothek, aber mit einer anderen Version verursacht werden.
Wenn Sie Maven oder ein anderes Framework verwenden und dieser Fehler fast zufällig auftritt, versuchen Sie eine Neuinstallation wie ...
clean install
Dies funktioniert besonders wahrscheinlich, wenn Sie das Objekt geschrieben haben und wissen, dass es die Methode hat. Hat für mich gearbeitet.
Dies kann auch das Ergebnis der Verwendung von Reflexion sein. Wenn Sie Code haben, der eine Klasse reflektiert und eine Methode nach Namen extrahiert (z. B. mit Class.getDeclaredMethod("someMethodName", .....)
), müssen Sie jedes Mal, wenn sich dieser Methodenname ändert, z. B. während eines Refactors, daran denken, die Parameter der Reflektionsmethode entsprechend zu aktualisieren neue Methodensignatur, oder der getDeclaredMethod
Aufruf löst a ausNoSuchMethodException
.
Wenn dies der Grund ist, sollte der Stack-Trace den Punkt anzeigen, an dem die Reflektionsmethode aufgerufen wird, und Sie müssen nur die Parameter aktualisieren, um sie an die tatsächliche Methodensignatur anzupassen.
Nach meiner Erfahrung tritt dies gelegentlich auf, wenn private Methoden / Felder getestet werden und eine TestUtilities
Klasse zum Extrahieren von Feldern für die Testüberprüfung verwendet wird. (Im Allgemeinen mit Legacy-Code, der nicht für Unit-Tests entwickelt wurde.)
Wenn Sie eine Webanwendung schreiben, stellen Sie sicher, dass sich im globalen Bibliotheksverzeichnis Ihres Containers und auch in Ihrer App keine widersprüchlichen Versionen einer JAR befinden. Möglicherweise wissen Sie nicht unbedingt, welches Glas vom Klassenladeprogramm verwendet wird.
z.B
Diese Probleme werden durch die Verwendung desselben Objekts in denselben zwei Klassen verursacht. Verwendete Objekte enthalten keine neue Methode, die die neue Objektklasse enthält.
Ex:
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$
Diese Probleme werden durch die begleitende ähnliche Klasse 02 verursacht (1 in src, 1 in der JAR-Datei hier ist gateway.jar).
Ich habe diesen Fehler gerade behoben, indem ich meine Eclipse neu gestartet und die Anwendung ausgeführt habe. Der Grund für meinen Fall kann sein, dass ich meine Quelldateien ersetze, ohne mein Projekt oder Eclipse zu schließen. Was zu unterschiedlichen Versionen der von mir verwendeten Klassen führte.
Versuchen Sie Folgendes: Entfernen Sie alle .class-Dateien in Ihren Projektverzeichnissen (und natürlich alle Unterverzeichnisse). Wiederaufbauen.
Manchmal mvn clean
(wenn Sie maven verwenden) werden .class-Dateien, die manuell von erstellt wurden, nicht bereinigt javac
. Und diese alten Dateien enthalten alte Signaturen, die dazu führen NoSuchMethodError
.
Einfach zu vorhandenen Antworten hinzufügen. Ich hatte dieses Problem mit Tomcat in Eclipse. Ich hatte eine Klasse gewechselt und folgende Schritte ausgeführt:
Reinigte und baute das Projekt in Eclpise
mvn sauber installieren
Trotzdem hatte ich den gleichen Fehler. Dann habe ich Tomcat gereinigt, das Tomcat-Arbeitsverzeichnis bereinigt und den Server neu gestartet, und mein Problem ist behoben. Hoffe das hilft jemandem
Um die ursprüngliche Frage zu beantworten. Laut Java Docs hier :
"NoSuchMethodError" Wird ausgelöst, wenn eine Anwendung versucht, eine angegebene Methode einer Klasse (entweder statisch oder instanziell) aufzurufen, und diese Klasse keine Definition dieser Methode mehr hat.
Normalerweise wird dieser Fehler vom Compiler abgefangen. Dieser Fehler kann nur zur Laufzeit auftreten, wenn sich die Definition einer Klasse nicht kompatibel geändert hat.
Ich habe dieses Problem in Eclipse behoben, indem ich eine Junit-Testdatei umbenannt habe.
In meinem Eclipse-Arbeitsbereich habe ich ein App-Projekt und ein Testprojekt.
Das Testprojekt hat das App-Projekt als erforderliches Projekt im Erstellungspfad.
Es wurde der NoSuchMethodError abgerufen.
Dann wurde mir klar, dass die Klasse im Testprojekt denselben Namen hatte wie die Klasse im App-Projekt.
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
Nach dem Umbenennen des Tests in den korrekten Namen "ProjectionTest.java" wurde die Ausnahme behoben.
Ich hatte den gleichen Fehler:
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)
Um dies zu lösen, überprüfte ich zunächst das Modulabhängigkeitsdiagramm ( click in your POM the combination -> Ctrl+Alt+Shift+U
oder right click in your POM -> Maven -> Show dependencies
), um zu verstehen, wo genau der Konflikt zwischen Bibliotheken war (Intelij IDEA). In meinem speziellen Fall hatte ich verschiedene Versionen von Jackson-Abhängigkeiten.
1) Also habe ich direkt in meinem POM des Projekts explizit die höchste Version hinzugefügt - 2.8.7 dieser beiden.
In Eigenschaften:
<jackson.version>2.8.7</jackson.version>
Und als Abhängigkeit:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2) Es kann aber auch mit Abhängigkeitsausschlüssen gelöst werden .
Nach dem gleichen Prinzip wie im folgenden Beispiel:
<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>
Abhängigkeiten mit unerwünschten Versionen werden von Ihrem Projekt ausgeschlossen.
In meinem Fall hatte ich ein Multi-Modul-Projekt und das Szenario war wie com.xyz.TestClass
im Modul A
und sowie im Modul B
und Modul A
war vom Modul abhängig B
. Beim Erstellen eines Assembly-JARs wurde meiner Meinung nach nur eine Version der Klasse beibehalten, wenn diese nicht über die aufgerufene Methode verfügt. Dann wurde eine NoSuchMethodError
Laufzeitausnahme angezeigt, aber die Kompilierung war in Ordnung.
Siehe auch: https://reflectoring.io/nosuchmethod/
Die obige Antwort erklärt sich sehr gut. Nur um eines hinzuzufügen. Wenn Sie Eclipse verwenden, verwenden Sie Strg + Umschalt + T und geben Sie die Paketstruktur der Klasse ein (z. B. gateway.smpp.PDUEventListener). Dort finden Sie alle Jars / Projekte, in denen sie vorhanden sind . Entfernen Sie unnötige Gläser aus dem Klassenpfad oder fügen Sie sie oben im Klassenpfad hinzu. Jetzt wird es richtig aufnehmen.
Ich bin auf ein ähnliches Problem gestoßen.
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
Schließlich stellte ich fest, dass die Hauptursache darin bestand, den Datentyp der Variablen zu ändern.
Employee.java
-> Enthält die Variable ( EmpId
), deren Datentyp von int
nach geändert wurde String
.ReportGeneration.java
-> Ruft den Wert mit dem Getter ab getEmpId()
.Wir sollen das Glas neu bündeln, indem wir nur die modifizierten Klassen einbeziehen. Da es keine Änderung gab, habe ReportGeneration.java
ich nur die Employee.class
In-Jar-Datei aufgenommen. Ich musste die ReportGeneration.class
Datei in das Glas aufnehmen, um das Problem zu lösen.
Ich hatte das gleiche Problem. Dies wird auch verursacht, wenn in Klassen Mehrdeutigkeiten bestehen. Mein Programm hat versucht, eine Methode aufzurufen, die in zwei JAR-Dateien vorhanden ist, die sich am selben Speicherort / Klassenpfad befinden. Löschen Sie eine JAR-Datei oder führen Sie Ihren Code so aus, dass nur eine JAR-Datei verwendet wird. Stellen Sie sicher, dass Sie nicht dieselbe JAR oder verschiedene Versionen derselben JAR verwenden, die dieselbe Klasse enthalten.
DISP_E_EXCEPTION [Schritt] [] [Z-JAVA-105 Java-Ausnahme java.lang.NoSuchMethodError (com.example.yourmethod)]
Meistens wird java.lang.NoSuchMethodError vom Compiler abgefangen, aber manchmal kann es zur Laufzeit auftreten. Wenn dieser Fehler zur Laufzeit auftritt, kann der einzige Grund die Änderung der Klassenstruktur sein, die ihn inkompatibel gemacht hat.
Beste Erklärung: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
Ich habe auch diesen Fehler festgestellt.
Mein Problem war, dass ich die Signatur einer Methode geändert habe, so etwas wie
void invest(Currency money){...}
in
void invest(Euro money){...}
Diese Methode wurde aus einem ähnlichen Kontext wie aufgerufen
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
Der Compiler schwieg in Bezug auf Warnungen / Fehler, da das Kapital sowohl Währung als auch Euro ist.
Das Problem trat aufgrund der Tatsache auf, dass ich nur die Klasse kompiliert habe, in der die Methode definiert wurde - Bank, aber nicht die Klasse, von der aus die Methode aufgerufen wird, die die main () -Methode enthält.
Dieses Problem tritt möglicherweise nicht zu häufig auf, da das Projekt am häufigsten manuell neu erstellt oder eine Build-Aktion automatisch ausgelöst wird, anstatt nur die eine geänderte Klasse zu kompilieren.
Mein Anwendungsfall war, dass ich eine JAR-Datei generiert habe, die als Hotfix verwendet werden sollte und die App.class nicht enthielt, da diese nicht geändert wurde. Es machte für mich Sinn, es nicht aufzunehmen, da ich die Basisklasse des ursprünglichen Arguments durch Vererbung beibehalten habe.
Die Sache ist, wenn Sie eine Klasse kompilieren, ist der resultierende Bytecode irgendwie statisch , mit anderen Worten, es ist eine harte Referenz .
Der ursprüngliche zerlegte Bytecode (generiert mit dem Javap-Tool) sieht folgendermaßen aus:
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
Nachdem der ClassLoader die neue kompilierte Bank.class geladen hat, findet er eine solche Methode nicht. Es sieht so aus, als ob sie entfernt und nicht geändert wurde, daher der genannte Fehler.
Hoffe das hilft.
Ich hatte ein ähnliches Problem mit meinem Gradle-Projekt mit Intelij. Ich habe es gelöst, indem ich das .gradle-Paket gelöscht habe (siehe Abbildung unten) und das Projekt neu erstellt habe. .gradle-Paket
NoSuchMethodError: Ich habe ein paar Stunden damit verbracht, dieses Problem zu beheben. Schließlich wurde es behoben, indem ich nur den Paketnamen umbenannte, bereinigte und erstellte ... Versuchen Sie zuerst, die Erstellung zu bereinigen, wenn dies nicht funktioniert. Versuchen Sie, den Klassennamen oder den Paketnamen und den sauberen Build umzubenennen. .es sollte behoben werden. Viel Glück.
Wenn sich Ihr Dateiname von dem Klassennamen unterscheidet, der die Hauptmethode enthält, besteht die Möglichkeit, dass dieser Fehler verursacht wird.