NoSuchMethodError in Java

1. Übersicht

In diesem Tutorial sehen wir uns den java.lang.NoSuchMethodError und einige Möglichkeiten an, damit umzugehen.

2. NoSuchMethodError

Wie der Name schon sagt, tritt der NoSuchMethodError auf, wenn eine bestimmte Methode nicht gefunden wird . Diese Methode kann entweder eine Instanzmethode oder eine statische Methode sein.

In den meisten Fällen können wir diesen Fehler beim Kompilieren abfangen. Daher ist es kein großes Problem. Aber manchmal kann es zur Laufzeit geworfen wird , dann findet es ein bisschen schwierig wird. Gemäß der Oracle-Dokumentation kann dieser Fehler zur Laufzeit auftreten, wenn eine Klasse nicht kompatibel geändert wurde.

Daher kann dieser Fehler in den folgenden Fällen auftreten. Erstens, wenn wir unseren Code nur teilweise neu kompilieren. Zweitens, wenn eine Versionsinkompatibilität mit den Abhängigkeiten in unserer Anwendung besteht, z. B. mit den externen Gläsern.

Beachten Sie, dass der Vererbungsbaum von NoSuchMethodError IncompatibleClassChangeError und LinkageError enthält. Diese Fehler sind mit einer inkompatiblen Klassenänderung nach der Kompilierung verbunden.

3. Beispiel für NoSuchMethodError

Lassen Sie uns diesen Fehler anhand eines Beispiels in Aktion sehen. Dazu erstellen wir zwei Klassen. Das erste ist SpecialToday, das die Specials für den Tag in einem Restaurant auflistet :

public class SpecialToday { private static String desert = "Chocolate Cake"; public static String getDesert() { return desert; } }

Das MainMenu der zweiten Klasse ruft Methoden von SpecialsToday auf:

public class MainMenu { public static void main(String[] args) { System.out.println("Today's Specials: " + getSpecials()); } public static String getSpecials() { return SpecialToday.getDesert(); } }

Hier wird die Ausgabe sein:

Today's Specials: Chocolate Cake

Als nächstes löschen wir die Methode getDesert () in SpecialToday und kompilieren nur diese aktualisierte Klasse neu. Dieses Mal stellen wir beim Ausführen unseres Hauptmenüs den folgenden Laufzeitfehler fest:

Exception in thread "main" java.lang.NoSuchMethodError: SpecialToday.getDesert()Ljava/lang/String;

4. Umgang mit NoSuchMethodError

Nun wollen wir sehen, wie wir damit umgehen können. Führen Sie für den obigen Code eine vollständige Bereinigung durch, einschließlich beider Klassen. Wir werden feststellen, dass der Fehler beim Kompilieren abgefangen wird. Wenn wir eine IDE wie Eclipse verwenden , wird diese noch früher erkannt, sobald wir SpecialsToday aktualisieren .

Wenn wir daher bei unseren Anwendungen als ersten Schritt auf diesen Fehler stoßen, führen wir eine vollständige saubere Kompilierung durch. Mit maven führen wir den Befehl mvn clean install aus .

Manchmal liegt das Problem bei den externen Abhängigkeiten unserer Anwendung. In diesem Fall überprüfen wir zuerst die Reihenfolge der Jars im Build-Pfad, der vom Klassenpfad-Loader abgerufen wird. Und wir werden das inkonsistente Glas verfolgen und aktualisieren.

Wenn wir diesen Fehler jedoch zur Laufzeit immer noch feststellen, müssen wir tiefer graben. Wir müssen sicherstellen, dass die Compile-Time- und die Runtime-Klassen und Jars die gleichen Versionen haben . Dazu können wir die Anwendung mit der Option -verbose: class ausführen , um die geladenen Klassen zu überprüfen. Wir können den Befehl wie folgt ausführen:

$ java -verbose:class com.baeldung.exceptions.nosuchmethoderror.MainMenu [0.014s][info][class,load] opened: /usr/lib/jvm/java-11-openjdk-amd64/lib/modules [0.015s][info][class,load] opened: /usr/share/java/java-atk-wrapper.jar [0.028s][info][class,load] java.lang.Object source: shared objects file [0.028s][info][class,load] java.io.Serializable source: shared objects file

Anhand dieser Informationen zu allen Klassen, die zur Laufzeit in die einzelnen Jars geladen werden, können wir die inkompatible Abhängigkeit verfolgen.

Wir sollten auch sicherstellen, dass es in zwei oder mehr Gläsern keine doppelten Klassen gibt . In den meisten Fällen hilft Maven dabei, widersprüchliche Abhängigkeiten direkt zu steuern . Darüber hinaus können wir den Befehl mvn dependency: tree ausführen , um den Abhängigkeitsbaum unseres Projekts wie folgt abzurufen:

$ mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] --------------------------- [INFO] Building nosuchmethoderror 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ nosuchmethoderror --- [INFO] com.baeldung.exceptions:nosuchmethoderror:jar:0.0.1-SNAPSHOT [INFO] \- org.junit:junit-bom:pom:5.7.0-M1:compile

Wir können die Bibliotheken und ihre Versionen in der von diesem Befehl generierten Liste überprüfen. Darüber hinaus können wir Abhängigkeiten auch mithilfe von Maven-Tags verwalten. Verwendung derTag können wir die problematische Abhängigkeit ausschließen. Verwendung der Tag, wir können verhindern, dass unerwünschte Abhängigkeiten im Glas oder im Krieg gebündelt werden.

5. Schlussfolgerung

In diesem Artikel haben wir NoSuchMethodError angesprochen . Wir haben die Ursache dieses Fehlers und Möglichkeiten zur Behandlung besprochen. Weitere Informationen zum richtigen Umgang mit Fehlern finden Sie in unserem Artikel zum Abfangen von Java-Fehlern.

Wie immer ist der in diesem Artikel vorgestellte Code auf GitHub verfügbar.