NoSuchMethodError en Java

1. Vue d'ensemble

Dans ce didacticiel, nous examinerons le java.lang.NoSuchMethodError et quelques moyens de le gérer.

2. NoSuchMethodError

Comme son nom l' indique, le NoSuchMethodError se produit lorsqu'une méthode particulière ne se trouve pas . Cette méthode peut être une méthode d'instance ou une méthode statique.

Dans la plupart des cas, nous pouvons détecter cette erreur au moment de la compilation. Par conséquent , ce n'est pas un gros problème. Cependant, parfois, il peut être lancé au moment de l'exécution , puis le trouver devient un peu difficile. Selon la documentation d'Oracle, cette erreur peut se produire au moment de l'exécution si une classe a été modifiée de manière incompatiible.

Par conséquent, nous pouvons rencontrer cette erreur dans les cas suivants. Premièrement, si nous ne faisons qu'une recompilation partielle de notre code. Deuxièmement, s'il existe une incompatibilité de version avec les dépendances de notre application, telles que les fichiers JAR externes.

Notez que l' arborescence d' héritage NoSuchMethodError inclut IncompatibleClassChangeError et LinkageError. Ces erreurs sont associées à un changement de classe incompatible après la compilation.

3. Exemple de NoSuchMethodError

Voyons cette erreur en action avec un exemple. Pour cela, nous allons créer deux classes. Le premier est SpecialToday qui listera les spécialités de la journée dans un restaurant:

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

La deuxième classe MainMenu appelle les méthodes de SpecialsToday:

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

Ici, la sortie sera:

Today's Specials: Chocolate Cake

Ensuite, nous supprimerons la méthode getDesert () dans SpecialToday et ne recompilerons que cette classe mise à jour. Cette fois, lorsque nous exécutons notre MainMenu, nous remarquons l'erreur d'exécution suivante:

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

4. Comment gérer NoSuchMethodError

Voyons maintenant comment nous pouvons gérer cela. Pour le code ci-dessus, faisons une compilation propre complète, y compris les deux classes. Nous remarquerons que l'erreur sera interceptée lors de la compilation. Si nous utilisons un IDE comme Eclipse , il sera détecté encore plus tôt, dès que nous mettrons à jour SpecialsToday .

Par conséquent, si nous rencontrons cette erreur avec nos applications, dans un premier temps, nous effectuerons une compilation propre complète. Avec maven, nous exécuterons la commande mvn clean install .

Parfois, le problème vient des dépendances externes de notre application. Dans ce cas, nous allons d'abord vérifier l'ordre des fichiers JAR dans le chemin de construction extrait par le chargeur de chemin de classe. Et nous allons tracer et mettre à jour le pot incohérent.

Cependant, si nous rencontrons toujours cette erreur au moment de l'exécution, nous devrons creuser plus profondément. Nous devrons nous assurer que les classes et fichiers JAR au moment de la compilation et à l'exécution ont les mêmes versions . Pour cela, nous pouvons exécuter l'application avec l'option -verbose: class pour vérifier les classes chargées. Nous pouvons exécuter la commande comme suit:

$ 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

En utilisant ces informations sur toutes les classes chargées dans les fichiers JAR individuels, pendant l'exécution, nous pouvons tracer la dépendance incompatible.

Nous devons également nous assurer qu'il n'y a pas de classes en double dans deux ou plusieurs jars. Dans la plupart des cas, maven aidera à contrôler directement les dépendances conflictuelles . De plus, nous pouvons exécuter la commande mvn dependency: tree pour obtenir l'arborescence de dépendances de notre projet comme suit:

$ 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

Nous pouvons vérifier les bibliothèques et leurs versions dans la liste générée par cette commande. De plus, nous pouvons également gérer les dépendances à l'aide des balises maven. En utilisant letag, nous pouvons exclure la dépendance problématique. En utilisant le tag, nous pouvons empêcher les dépendances indésirables d'être regroupées dans le fichier jar ou war.

5. Conclusion

Dans cet article, nous avons abordé NoSuchMethodError . Nous avons discuté de la cause de cette erreur et des moyens de la gérer. Pour plus de détails sur la manière de gérer correctement les erreurs, veuillez consulter notre article sur la détection des erreurs Java.

Comme toujours, le code présenté dans cet article est disponible à l'adresse over sur GitHub.