NoSuchMethodError in Java

1. Panoramica

In questo tutorial, esamineremo java.lang.NoSuchMethodError e alcuni modi per gestirlo.

2. NoSuchMethodError

Come suggerisce il nome, il NoSuchMethodError si verifica quando un particolare metodo non viene trovato . Questo metodo può essere un metodo di istanza o un metodo statico.

Nella maggior parte dei casi, siamo in grado di rilevare questo errore in fase di compilazione. Quindi , non è un grosso problema. Tuttavia, a volte potrebbe essere lanciato in runtime , quindi trovarlo diventa un po 'difficile. Secondo la documentazione Oracle, questo errore può verificarsi in fase di esecuzione se una classe è stata modificata in modo incompatibile.

Pertanto, potremmo riscontrare questo errore nei seguenti casi. In primo luogo, se facciamo solo una ricompilazione parziale del nostro codice. In secondo luogo, se c'è un'incompatibilità di versione con le dipendenze nella nostra applicazione, come i jar esterni.

Si noti che il NoSuchMethodError eredità albero comprende IncompatibleClassChangeError e LinkageError. Questi errori sono associati a un cambio di classe incompatibile dopo la compilazione.

3. Esempio di NoSuchMethodError

Vediamo questo errore in azione con un esempio. Per questo, creeremo due classi. Il primo è SpecialToday che elencherà le specialità del giorno in un ristorante:

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

La seconda classe MainMenu chiama i metodi da SpecialsToday:

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

Qui l'output sarà:

Today's Specials: Chocolate Cake

Successivamente, elimineremo il metodo getDesert () in SpecialToday e ricompileremo solo questa classe aggiornata. Questa volta quando eseguiamo il nostro MainMenu, notiamo il seguente errore di runtime:

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

4. Come gestire NoSuchMethodError

Ora vediamo come possiamo gestire questo. Per il codice precedente, eseguiamo una compilazione pulita completa, incluse entrambe le classi. Noteremo che l'errore verrà rilevato durante la compilazione. Se utilizziamo un IDE come Eclipse , verrà rilevato anche prima, non appena aggiorneremo SpecialsToday .

Quindi se ci imbattiamo in questo errore con le nostre applicazioni, come primo passo, faremo una compilazione completamente pulita. Con Maven, eseguiremo il comando mvn clean install .

A volte il problema è con le dipendenze esterne della nostra applicazione. In questo caso, controlleremo prima l'ordine dei jar nel percorso di compilazione tirato dal caricatore di classpath. E tracceremo e aggiorneremo il jar incoerente.

Tuttavia, se riscontriamo ancora questo errore in fase di esecuzione, dovremo scavare più a fondo. Dovremo assicurarci che le classi e i jar in fase di compilazione e runtime abbiano le stesse versioni . Per questo, possiamo eseguire l'applicazione con l'opzione -verbose: class per controllare le classi caricate. Possiamo eseguire il comando come segue:

$ 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

Utilizzando queste informazioni su tutte le classi caricate nei singoli jar, durante il runtime, possiamo tracciare la dipendenza incompatibile.

Dovremmo anche assicurarci che non ci siano classi duplicate in due o più vasi. Nella maggior parte dei casi, Maven aiuterà a controllare direttamente le dipendenze in conflitto . Inoltre, possiamo eseguire il comando mvn dependency: tree per ottenere l'albero delle dipendenze del nostro progetto come segue:

$ 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

Possiamo controllare le librerie e le loro versioni nell'elenco generato da questo comando. Inoltre, possiamo anche gestire le dipendenze utilizzando i tag Maven. Usando iltag, possiamo escludere la dipendenza problematica. Usando il tag, possiamo impedire che dipendenze indesiderate vengano raggruppate nel jar o war.

5. conclusione

In questo articolo, abbiamo affrontato NoSuchMethodError . Abbiamo discusso la causa di questo errore e anche i modi per gestirlo. Per maggiori dettagli su come gestire correttamente gli errori, fare riferimento al nostro articolo su come rilevare gli errori Java.

Come sempre, il codice presentato in questo articolo è disponibile su GitHub.