NoSuchMethodError in Java

1. Overzicht

In deze tutorial kijken we naar de java.lang.NoSuchMethodError en enkele manieren om ermee om te gaan.

2. NoSuchMethodError

Zoals de naam al doet vermoeden, de NoSuchMethodError treedt op wanneer een bepaalde methode niet wordt gevonden. Deze methode kan een instantiemethode of een statische methode zijn.

In de meeste gevallen,we kunnen deze fout tijdens het compileren opvangen. Vandaar, het is geen groot probleem. Echter, soms kan het tijdens runtime worden gegooid, dan wordt het een beetje moeilijk om het te vinden. Volgens de Oracle-documentatie kan deze fout optreden tijdens runtime als een klasse incompatibel is gewijzigd.

Daarom kunnen we deze fout in de volgende gevallen tegenkomen. Ten eerste, als we slechts een gedeeltelijke hercompilatie doen van onze code. Ten tweede, als dat zo is versie incompatibiliteit met de afhankelijkheden in onze applicatie, zoals de externe potten.

Merk op dat de NoSuchMethodError overervingsboom omvat IncompatibleClassChangeError en LinkageError. Deze fouten houden verband met een incompatibele klassewijziging na compilatie.

3. Voorbeeld van NoSuchMethodError

Laten we deze fout in actie bekijken met een voorbeeld. Hiervoor maken we twee klassen. De eerste is SpecialVandaag die de specials voor de dag in een restaurant opsomt:

openbare klasse SpecialToday {private static String desert = "Chocoladetaart"; openbare statische String getDesert () {return desert; }}

De tweede klas Hoofdmenu roept methoden aan van SpecialsVandaag:

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

Hier zal de output zijn:

De specialiteiten van vandaag: chocoladetaart

Vervolgens verwijderen we de methode getDesert () in SpecialVandaag en hercompileer alleen deze bijgewerkte klasse. Deze keer wanneer we onze Hoofdmenu, we merken de volgende runtime-fout op:

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

4. Hoe te gebruiken NoSuchMethodError

Laten we nu eens kijken hoe we dit kunnen aanpakken. Laten we voor de bovenstaande code doe een volledige schone compilatie, inclusief beide klassen. We zullen merken dat de fout wordt opgemerkt terwijl we aan het compileren zijn. Als we een IDE zoals Eclipse, het zal zelfs eerder worden gedetecteerd, zodra we updaten SpecialsVandaag.

Dus als we deze fout tegenkomen met onze applicaties, zullen we als eerste stap een volledig schone compilatie uitvoeren. Met maven zullen we de mvn schone installatie opdracht.

Soms ligt het probleem bij de externe afhankelijkheden van onze applicatie. In dit geval gaan we eerst controleer de volgorde van de potten in het build-pad getrokken door de classpath-lader. En we zullen de inconsistente pot traceren en bijwerken.

Als we deze fout echter nog steeds tegenkomen tijdens runtime, zullen we dieper moeten graven. We zullen moeten zorg ervoor dat de compilatietijd en de runtime-klassen en jars dezelfde versies hebben. Hiervoor kunnen we voer de applicatie uit met de optie -verbose: class om de geladen klassen te controleren. We kunnen de opdracht als volgt uitvoeren:

$ java -verbose: class com.baeldung.exceptions.nosuchmethoderror.MainMenu [0.014s] [info] [class, load] geopend: / usr / lib / jvm / java-11-openjdk-amd64 / lib / modules [0.015s ] [info] [class, load] geopend: /usr/share/java/java-atk-wrapper.jar [0.028s] [info] [class, load] java.lang.Object source: bestand met gedeelde objecten [0.028s ] [info] [klasse, belasting] java.io.Serialiseerbare bron: bestand met gedeelde objecten

Met behulp van deze informatie over alle klassen die in de individuele jars worden geladen, kunnen we tijdens runtime de incompatibele afhankelijkheid traceren.

We zouden ook moeten zorg ervoor dat er geen dubbele klassen zijn in twee of meer potten. In de meeste gevallen helpt maven conflicterende afhankelijkheden te beheersen direct. Bovendien kunnen we het mvn-afhankelijkheid: boom commando om de afhankelijkheidsboom van ons project als volgt op te halen:

$ mvn afhankelijkheid: boom [INFO] Scannen naar projecten ... [INFO] [INFO] --------------------------- [INFO] Nosuchmethoderror 0.0.1-SNAPSHOT [INFO] -------------------------------- [jar] ----- bouwen ---------------------------- [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: compileren

We kunnen de bibliotheken en hun versies controleren in de lijst die door deze opdracht wordt gegenereerd. Bovendien kunnen we afhankelijkheden ook beheren met behulp van maven-tags. De ... gebruiken tag, kunnen we de problematische afhankelijkheid uitsluiten. De ... gebruiken tag, kunnen we voorkomen dat ongewenste afhankelijkheden worden gebundeld in de pot of oorlog.

5. Conclusie

In dit artikel hebben we ingegaan op NoSuchMethodError. We hebben de oorzaak van deze fout besproken en ook manieren om ermee om te gaan. Raadpleeg ons artikel over het opsporen van Java-fouten voor meer informatie over het correct afhandelen van fouten.

Zoals altijd is de code die in dit artikel wordt gepresenteerd, beschikbaar op GitHub.