Question

je reçois un NoSuchMethodError erreur lors de l'exécution de mon programme Java.Qu'est-ce qui ne va pas et comment puis-je y remédier ?

Était-ce utile?

La solution

Sans plus d'informations, il est difficile d'identifier le problème, mais la cause première est que vous avez probablement compilé une classe avec une version différente de la classe à laquelle il manque une méthode, que celle que vous utilisez lors de son exécution.

Regardez la trace de la pile...Si l'exception apparaît lors de l'appel d'une méthode sur un objet dans une bibliothèque, vous utilisez probablement des versions distinctes de la bibliothèque lors de la compilation et de l'exécution.Assurez-vous d’avoir la bonne version aux deux endroits.

Si l'exception apparaît lors de l'appel d'une méthode sur des objets instanciés par des classes toi fait, alors votre processus de construction semble être défectueux.Assurez-vous que les fichiers de classe que vous exécutez réellement sont mis à jour lors de la compilation.

Autres conseils

J'avais votre problème et voici comment je l'ai résolu.Les étapes suivantes constituent une méthode efficace pour ajouter une bibliothèque.J'avais bien fait les deux premières étapes, mais je n'avais pas fait la dernière en faisant glisser le fichier ".jar" directement du système de fichiers vers le dossier "lib" de mon projet Eclipse.De plus, j'ai dû supprimer la version précédente de la bibliothèque à la fois du chemin de construction et du dossier "lib".

Étape 1 - Ajoutez .jar au chemin de construction

enter image description here

Étape 2 - Associer les sources et les javadocs (facultatif)

enter image description here

Étape 3 - Faites glisser le fichier .jar dans le dossier "lib" (non facultatif)

enter image description here

Notez que dans le cas de la réflexion, vous obtenez un NoSuchMethodException, alors qu'avec un code non réfléchissant, vous obtenez NoSuchMethodError.J'ai tendance à aller chercher dans des endroits très différents lorsque je suis confronté à l'un ou à l'autre.

Si vous avez accès à la modification des paramètres JVM, l'ajout d'une sortie détaillée devrait vous permettre de voir quelles classes sont chargées à partir de quels JAR.

java -verbose:class <other args>

Lorsque votre programme est exécuté, la JVM doit transférer vers des informations standard telles que :

...

[Junit.framework.Assert chargé à partir du fichier:/C:/Program%20Files/junit3.8.2/junit.jar]

...

Cela est généralement dû à l'utilisation d'un système de build tel que Fourmi Apache qui compile uniquement les fichiers Java lorsque le fichier Java est plus récent que le fichier de classe.Si la signature d'une méthode change et que les classes utilisaient l'ancienne version, les choses peuvent ne pas être compilées correctement.La solution habituelle consiste à effectuer une reconstruction complète (généralement "ant clean" puis "ant").

Parfois, cela peut également être dû à la compilation sur une version d'une bibliothèque mais à l'exécution sur une version différente.

Si vous utilisez Maven ou un autre framework, et vous obtenez cette erreur presque aléatoirement, essayez une nouvelle installation comme...

clean install

Cela est particulièrement susceptible de fonctionner si vous avez écrit l'objet et que vous savez qu'il possède la méthode.A fonctionné pour moi.

Cela peut aussi être le résultat de l’utilisation de la réflexion.Si vous avez du code qui reflète une classe et extrait une méthode par son nom (par exemple :avec Class.getDeclaredMethod("someMethodName", .....)), puis chaque fois que le nom de la méthode change, par exemple lors d'un refactor, vous devrez vous rappeler de mettre à jour les paramètres de la méthode de réflexion pour qu'ils correspondent à la nouvelle signature de la méthode, ou au getDeclaredMethod l'appel lancera un NoSuchMethodException.

Si tel est le cas, la trace de la pile doit indiquer le point auquel la méthode de réflexion est invoquée et il vous suffira de mettre à jour les paramètres pour qu'ils correspondent à la signature réelle de la méthode.

D'après mon expérience, cela se produit occasionnellement lors de tests unitaires de méthodes/champs privés et de l'utilisation d'un TestUtilities classe pour extraire les champs pour la vérification des tests.(Généralement avec du code existant qui n'a pas été conçu pour les tests unitaires.)

Si vous écrivez une application Web, assurez-vous que vous n'avez pas de versions conflictuelles d'un fichier jar dans le répertoire de bibliothèque global de votre conteneur ainsi que dans votre application.Vous ne savez peut-être pas nécessairement quel fichier jar est utilisé par le chargeur de classe.

par exemple.

  • tomcat/common/lib
  • monappweb/WEB-INF/lib

Ces problèmes sont causés par l’utilisation du même objet dans les deux mêmes classes.Les objets utilisés ne contiennent pas de nouvelle méthode qui contient la nouvelle classe d'objets.

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$ 

Ces problèmes sont causés par la classe similaire 02 concomitante (1 dans src, 1 dans le fichier jar ici est gateway.jar)

Cela signifie que la méthode correspondante n'est pas présente dans la classe :

  1. Si vous utilisez jar, décompilez et vérifiez si la version respective de jar a la classe appropriée.
  2. Vérifiez si vous avez compilé la classe appropriée à partir de votre source.

Pour moi, cela s'est produit parce que j'ai changé le type d'argument dans la fonction, de l'objet a à la chaîne a.Je pourrais le résoudre avec clean et reconstruire

Je viens de résoudre cette erreur en redémarrant mon Eclipse et en exécutant l'application.La raison de mon cas peut être due au fait que je remplace mes fichiers sources sans fermer mon projet ou Eclipse.Ce qui a provoqué une version différente des classes que j'utilisais.

Essayez de cette façon :supprimez tous les fichiers .class sous les répertoires de votre projet (et, bien sûr, tous les sous-répertoires).Reconstruire.

Parfois mvn clean (si vous utilisez maven) ne nettoie pas les fichiers .class créés manuellement par javac.Et ces anciens fichiers contiennent d'anciennes signatures, ce qui conduit à NoSuchMethodError.

Il suffit d'ajouter aux réponses existantes.J'étais confronté à ce problème avec Tomcat dans Eclipse.J'avais changé une classe et suivi les étapes suivantes,

  1. Nettoyé et construit le projet en eclpise

  2. mvn installation propre

  3. Tomcat redémarré

J'étais toujours confronté à la même erreur.Alors J'ai nettoyé Tomcat, nettoyé le répertoire de travail de Tomcat et j'ai redémarré le serveur et mon problème a disparu.J'espère que cela aide quelqu'un

J'ai résolu ce problème dans Eclipse en renommant un fichier de test Junit.
Dans mon espace de travail Eclipse, j'ai un projet d'application et un projet de test.
Le projet Test a le projet App comme projet obligatoire sur le chemin de génération.

J'ai commencé à obtenir le NoSuchMethodError.
Ensuite, j'ai réalisé que la classe du projet Test portait le même nom que la classe du projet App.

App/  
  src/
     com.example/  
       Projection.java
Test/  
  src/
     com.example/
       Projection.java

Après avoir renommé le test avec le nom correct « ProjectionTest.java », l'exception a disparu.

J'ai rencontré un problème similaire lorsque je modifiais les signatures de méthode dans mon application.Le nettoyage et la reconstruction de mon projet ont résolu le problème "NoSuchMethodError".

La réponse ci-dessus explique très bien ... juste pour ajouter une chose si vous utilisez Eclipse Utilisez Ctrl + Shift + T et entrez la structure de la classe de package (par exemple:gateway.smpp.PDUEventListener ), vous trouverez tous les pots/projets où il est présent.Supprimez les fichiers jar inutiles du chemin de classe ou ajoutez-les ci-dessus dans le chemin de classe.Maintenant, il va récupérer le bon.

J'ai rencontré un problème similaire.

Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I

Finalement, j'ai identifié que la cause première était le changement du type de données de la variable.

  1. Employee.java --> Contient la variable (EmpId) dont le type de données a été modifié de int à String.
  2. ReportGeneration.java --> Récupère la valeur à l'aide du getter, getEmpId().

Nous sommes censés regrouper le pot en incluant uniquement les classes modifiées.Comme il n'y a eu aucun changement dans ReportGeneration.java J'incluais seulement le Employee.class dans le fichier Jar.J'ai dû inclure le ReportGeneration.class fichier dans le pot pour résoudre le problème.

J'ai eu le même problème.Cela se produit également lorsqu'il existe une ambiguïté dans les classes.Mon programme essayait d'invoquer une méthode qui était présente dans deux fichiers JAR présents au même emplacement/chemin de classe.Supprimez un fichier JAR ou exécutez votre code de telle sorte qu'un seul fichier JAR soit utilisé.Vérifiez que vous n'utilisez pas le même JAR ou des versions différentes du même JAR contenant la même classe.

DISP_E_EXCEPTION [étape] [] [Exception Java Z-JAVA-105 java.lang.NoSuchMethodError(com.example.yourmethod)]

Pour répondre à la question initiale.D'après la documentation Java ici:

"NoSuchMethodError" Levé si une application tente d'appeler une méthode spécifiée d'une classe (statique ou instance) et que cette classe n'a plus de définition de cette méthode.

Normalement, cette erreur est détectée par le compilateur ;cette erreur ne peut se produire qu'au moment de l'exécution si la définition d'une classe a changé de manière incompatible.

  1. Si cela se produit au moment de l’exécution, vérifiez que la classe contenant la méthode se trouve dans le chemin de classe.
  2. Vérifiez si vous avez ajouté une nouvelle version de JAR et si la méthode est compatible.

La plupart du temps, java.lang.NoSuchMethodError est détecté par le compilateur, mais cela peut parfois se produire au moment de l'exécution.Si cette erreur se produit au moment de l’exécution, la seule raison pourrait être le changement dans la structure de classe qui la rendait incompatible.

Meilleure explication : https://www.journaldev.com/14538/java-lang-nosuchmethoderror

J'ai également rencontré cette erreur.

Mon problème était que j'avais modifié la signature d'une méthode, quelque chose comme

void invest(Currency money){...}

dans

void invest(Euro money){...}

Cette méthode a été invoquée dans un contexte similaire à

public static void main(String args[]) {
    Bank myBank = new Bank();

    Euro capital = new Euro();
    myBank.invest(capital);
}

Le compilateur est resté silencieux en ce qui concerne les avertissements/erreurs, car le capital est à la fois la monnaie et l'euro.

Le problème est dû au fait que j'ai uniquement compilé la classe dans laquelle la méthode a été définie - Bank, mais pas la classe à partir de laquelle la méthode est appelée, qui contient la méthode main().

Ce problème n'est pas quelque chose que vous pourriez rencontrer trop souvent, car le plus souvent, le projet est reconstruit manuellement ou une action Build est déclenchée automatiquement, au lieu de simplement compiler la classe modifiée.

Mon cas d'utilisation était que j'avais généré un fichier .jar qui devait être utilisé comme correctif, qui ne contenait pas l'App.class car celui-ci n'avait pas été modifié.Il me paraissait logique de ne pas l'inclure car j'ai conservé la classe de base de l'argument initial grâce à l'héritage.

Le fait est que lorsque vous compilez une classe, le bytecode résultant est en quelque sorte statique, en d'autres termes, c'est un référence matérielle.

Le bytecode original désassemblé (généré avec l'outil javap) ressemble à ceci :

 #7 = Methodref          #2.#22         // Bank.invest:(LCurrency;)V

Une fois que le ClassLoader a chargé la nouvelle Bank.class compilée, il ne trouvera pas une telle méthode, il semble qu'elle ait été supprimée et non modifiée, d'où l'erreur nommée.

J'espère que cela t'aides.

Le problème dans mon cas était d'avoir deux versions de la même bibliothèque dans le chemin de construction.L'ancienne version de la bibliothèque n'avait pas cette fonction, contrairement à la plus récente.

J'ai eu un problème similaire avec mon projet Gradle utilisant Intelij.Je l'ai résolu en supprimant le package .gradle (voir capture d'écran ci-dessous) et en reconstruisant le projet.Paquet .gradle

NoSuchMethodError :J'ai passé quelques heures à résoudre ce problème, je l'ai finalement résolu en renommant simplement le nom du package, en le nettoyant et en le construisant...Essayez d'abord une construction propre si cela ne fonctionne pas, essayez de renommer le nom de la classe ou le nom du package et une construction propre... cela devrait être corrigé.Bonne chance.

J'ai eu la même erreur :

  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)

Pour le résoudre, j'ai vérifié, d'abord, Diagramme de dépendance des modules (click in your POM the combination -> Ctrl+Alt+Shift+U ou right click in your POM -> Maven -> Show dependencies) pour comprendre où était exactement le conflit entre les bibliothèques (Intelij IDEA).Dans mon cas particulier, j'avais différentes versions des dépendances de Jackson.

enter image description here enter image description here

1) J'ai donc ajouté directement dans mon POM du projet explicitement la version la plus élevée - 2.8.7 de ces deux.

Dans les propriétés :

<jackson.version>2.8.7</jackson.version>

Et comme dépendance :

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

2) Mais cela peut aussi être résolu en utilisant Exclusions de dépendances.

Par le même principe que ci-dessous en exemple :

  <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>

Les dépendances avec une version indésirable seront exclues de votre projet.

Si le nom de votre fichier est différent du nom de la classe qui contient la méthode principale, il est possible que cette erreur se produise.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top