Domanda

Sto ricevendo un NoSuchMethodError errore durante l'esecuzione del mio programma Java.Cosa c'è che non va e come posso risolverlo?

È stato utile?

Soluzione

Senza ulteriori informazioni è difficile individuare il problema, ma la causa principale è che molto probabilmente hai compilato una classe con una versione diversa della classe a cui manca un metodo rispetto a quella che stai utilizzando durante l'esecuzione.

Guarda l'analisi dello stack...Se l'eccezione appare quando si chiama un metodo su un oggetto in una libreria, molto probabilmente stai utilizzando versioni separate della libreria durante la compilazione e l'esecuzione.Assicurati di avere la versione giusta in entrambi i posti.

Se l'eccezione viene visualizzata quando si chiama un metodo su oggetti istanziati dalle classi Voi fatto, il processo di creazione sembra essere difettoso.Assicurati che i file di classe che stai effettivamente eseguendo vengano aggiornati durante la compilazione.

Altri suggerimenti

Stavo riscontrando il tuo problema ed è così che l'ho risolto.I passaggi seguenti rappresentano un modo efficace per aggiungere una libreria.Avevo eseguito correttamente i primi due passaggi, ma non avevo eseguito l'ultimo trascinando il file ".jar" direttamente dal file system nella cartella "lib" del mio progetto Eclipse.Inoltre, ho dovuto rimuovere la versione precedente della libreria sia dal percorso di compilazione che dalla cartella "lib".

Passaggio 1: aggiungi .jar al percorso di creazione

enter image description here

Passaggio 2: associare origini e javadoc (facoltativo)

enter image description here

Passaggio 3: trascina effettivamente il file .jar nella cartella "lib" (non facoltativo)

enter image description here

Nota che nel caso della riflessione, ottieni un NoSuchMethodException, mentre con il codice non riflettente ottieni NoSuchMethodError.Tendo a cercare in posti molto diversi quando mi confronto con l'uno rispetto all'altro.

Se hai accesso per modificare i parametri JVM, l'aggiunta di output dettagliato dovrebbe consentirti di vedere quali classi vengono caricate da quali JAR.

java -verbose:class <other args>

Quando il programma viene eseguito, la JVM dovrebbe eseguire il dump di informazioni standard come:

...

[Caricato junit.framework.Assert dal file:/C:/Program%20Files/junit3.8.2/junit.jar]

...

Questo di solito è causato dall'utilizzo di un sistema di compilazione come Formica Apache che compila solo file Java quando il file Java è più recente del file di classe.Se la firma di un metodo cambia e le classi utilizzavano la versione precedente, le cose potrebbero non essere compilate correttamente.La soluzione abituale è eseguire una ricostruzione completa (di solito "ant clean" quindi "ant").

A volte questo può essere causato anche quando si compila con una versione di una libreria ma si esegue con una versione diversa.

Se si utilizza Esperto di o un altro framework e ricevi questo errore in modo quasi casuale, prova un'installazione pulita come...

clean install

È particolarmente probabile che funzioni se hai scritto tu l'oggetto e sai che ha il metodo.Ha funzionato per me.

Questo può anche essere il risultato dell'utilizzo della riflessione.Se hai del codice che si riflette su una classe ed estrae un metodo per nome (ad esempio:con Class.getDeclaredMethod("someMethodName", .....)) quindi ogni volta che il nome del metodo cambia, ad esempio durante un refactoring, dovrai ricordarti di aggiornare i parametri del metodo di riflessione in modo che corrispondano alla nuova firma del metodo o al getDeclaredMethod la chiamata genererà a NoSuchMethodException.

Se questo è il motivo, l'analisi dello stack dovrebbe mostrare il punto in cui viene richiamato il metodo di riflessione e dovrai solo aggiornare i parametri in modo che corrispondano alla firma effettiva del metodo.

Nella mia esperienza, questo si verifica occasionalmente quando si testano metodi/campi privati ​​e si utilizza a TestUtilities classe per estrarre i campi per la verifica del test.(In genere con codice legacy che non è stato progettato pensando ai test unitari.)

Se stai scrivendo una webapp, assicurati di non avere versioni in conflitto di un jar nella directory della libreria globale del tuo contenitore e anche nella tua app.Potresti non necessariamente sapere quale jar viene utilizzato dal classloader.

per esempio.

  • tomcat/comune/lib
  • miawebapp/WEB-INF/lib

Questi problemi sono causati dall'utilizzo dello stesso oggetto nelle stesse due classi.Gli oggetti utilizzati non contengono il nuovo metodo che è stato aggiunto contenuto nella nuova classe di oggetti.

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$ 

Questi problemi sono causati dalla concomitante classe simile 02 (1 in src, 1 nel file jar qui è gateway.jar)

Significa che il rispettivo metodo non è presente nella classe:

  1. Se stai usando jar, decompila e controlla se la rispettiva versione di jar ha la classe corretta.
  2. Controlla se hai compilato la classe corretta dalla tua fonte.

Per me è successo perché ho cambiato il tipo di argomento nella funzione, da Oggetto a, a Stringa a.Potrei risolverlo con clean e build di nuovo

Ho appena risolto questo errore riavviando Eclipse ed eseguendo l'applicazione.Il motivo del mio caso potrebbe essere perché sostituisco i miei file sorgente senza chiudere il mio progetto o Eclipse.Ciò ha causato una versione diversa delle lezioni che stavo utilizzando.

Prova in questo modo:rimuovi tutti i file .class nelle directory del tuo progetto (e, ovviamente, tutte le sottodirectory).Ricostruire.

A volte mvn clean (se stai usando Maven) non pulisce i file .class creati manualmente da javac.E quei vecchi file contengono vecchie firme, che portano a NoSuchMethodError.

Sto solo aggiungendo alle risposte esistenti.Stavo affrontando questo problema con Tomcat in Eclipse.Avevo cambiato una classe e ho eseguito i seguenti passaggi,

  1. Pulito e costruito il progetto in eclpise

  2. mvn installazione pulita

  3. Tomcat riavviato

Tuttavia stavo affrontando lo stesso errore.Poi Ho pulito Tomcat, ho pulito la directory di lavoro di Tomcat e ho riavviato il server e il mio problema è scomparso.Spero che questo aiuti qualcuno

Ho risolto questo problema in Eclipse rinominando un file di test Junit.
Nel mio spazio di lavoro Eclipse ho un progetto App e un progetto Test.
Il progetto Test ha il progetto App come progetto obbligatorio nel percorso di compilazione.

Ho iniziato a ricevere il NoSuchMethodError.
Poi mi sono reso conto che la classe nel progetto Test aveva lo stesso nome della classe nel progetto App.

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

Dopo aver rinominato il test con il nome corretto "ProjectionTest.java", l'eccezione è scomparsa.

Ho riscontrato un problema simile mentre stavo modificando le firme dei metodi nella mia applicazione.La pulizia e la ricostruzione del mio progetto hanno risolto il problema "NoSuchMethodError".

La risposta sopra spiega molto bene .. basta aggiungere una cosa se si utilizza l'utilizzo di eclipse usa ctrl+shift+t e immettere la struttura del pacchetto della classe (ad es.:gateway.smpp.PDUEventListener ), troverai tutti i jar/progetti in cui è presente.Rimuovi i jar non necessari dal classpath o aggiungi sopra nel classpath.Ora ne prenderà uno corretto.

Ho riscontrato un problema simile.

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

Alla fine ho identificato che la causa principale stava cambiando il tipo di dati della variabile.

  1. Employee.java --> Contiene la variabile (EmpId) il cui tipo di dati è stato modificato da int A String.
  2. ReportGeneration.java --> Recupera il valore utilizzando il getter, getEmpId().

Dovremmo ricomporre il jar includendo solo le classi modificate.Poiché non vi è stato alcun cambiamento ReportGeneration.java Stavo includendo solo il Employee.class nel file Jar.Ho dovuto includere il ReportGeneration.class file nel barattolo per risolvere il problema.

Ho avuto lo stesso problema.Ciò si verifica anche quando c'è un'ambiguità nelle classi.Il mio programma stava tentando di invocare un metodo presente in due file JAR presenti nella stessa posizione/percorso classe.Elimina un file JAR o esegui il codice in modo tale da utilizzare un solo file JAR.Controlla di non utilizzare lo stesso JAR o versioni diverse dello stesso JAR che contengono la stessa classe.

DISP_E_EXCEPTION [passaggio] [] [Z-JAVA-105 Eccezione Java java.lang.NoSuchMethodError(com.example.yourmethod)]

Per rispondere alla domanda originale.Secondo i documenti Java Qui:

"NoSuchMethodError" Emesso se un'applicazione tenta di chiamare un metodo specificato di una classe (statico o di istanza) e quella classe non ha più una definizione di quel metodo.

Normalmente questo errore viene rilevato dal compilatore;questo errore può verificarsi solo in fase di esecuzione se la definizione di una classe è cambiata in modo incompatibile.

  1. Se ciò accade in fase di esecuzione, controlla che la classe contenente il metodo sia nel percorso classe.
  2. Controlla se hai aggiunto una nuova versione di JAR e il metodo è compatibile.

La maggior parte delle volte java.lang.NoSuchMethodError viene rilevato dal compilatore, ma a volte può verificarsi in fase di runtime.Se questo errore si verifica in fase di esecuzione, l'unico motivo potrebbe essere il cambiamento nella struttura della classe che lo ha reso incompatibile.

Migliore spiegazione: https://www.journaldev.com/14538/java-lang-nosuchmethoderror

Anch'io ho riscontrato questo errore.

Il mio problema era che ho cambiato la firma di un metodo, qualcosa del genere

void invest(Currency money){...}

in

void invest(Euro money){...}

Questo metodo è stato invocato da un contesto simile a

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

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

Il compilatore ha taciuto riguardo agli avvertimenti/errori, poiché il capitale è sia valuta che euro.

Il problema è apparso perché ho compilato solo la classe in cui è stato definito il metodo - Bank, ma non la classe da cui viene chiamato il metodo, che contiene il metodo main().

Questo problema non è qualcosa che potresti incontrare troppo spesso, poiché molto spesso il progetto viene ricostruito manualmente o un'azione di compilazione viene attivata automaticamente, invece di compilare semplicemente l'unica classe modificata.

Il mio caso d'uso era che generavo un file .jar che doveva essere utilizzato come hotfix, che non conteneva App.class poiché non era stato modificato.Per me aveva senso non includerlo poiché ho mantenuto la classe base dell'argomento iniziale tramite ereditarietà.

Il fatto è che, quando compili una classe, il bytecode risultante è in un certo senso statico, in altre parole, è a riferimento rigido.

Il bytecode originale disassemblato (generato con lo strumento javap) si presenta così:

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

Dopo che ClassLoader ha caricato la nuova Bank.class compilata, non troverà tale metodo, sembra come se fosse stato rimosso e non modificato, da qui l'errore indicato.

Spero che questo ti aiuti.

Il problema nel mio caso era avere due versioni della stessa libreria nel percorso di compilazione.La versione precedente della libreria non aveva la funzione, mentre quella più recente sì.

Ho avuto un problema simile con il mio progetto Gradle utilizzando Intelij.L'ho risolto eliminando il pacchetto .gradle (vedi screenshot sotto) e ricostruendo il progetto.Pacchetto .gradle

NoSuchMethodError:Ho passato un paio d'ore a risolvere questo problema, alla fine l'ho risolto semplicemente rinominando il nome del pacchetto, pulisci e crea ...Prova prima la build pulita se non funziona, prova a rinominare il nome della classe o il nome del pacchetto e la build pulita... dovrebbe essere risolto.Buona fortuna.

Ho avuto lo stesso errore:

  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)

Per risolverlo ho controllato, in primo luogo, Diagramma delle dipendenze del modulo (click in your POM the combination -> Ctrl+Alt+Shift+U O right click in your POM -> Maven -> Show dependencies) per capire dove fosse esattamente il conflitto tra le biblioteche (Intelij IDEA).Nel mio caso particolare, avevo diverse versioni delle dipendenze di Jackson.

enter image description here enter image description here

1) Quindi, ho aggiunto direttamente nel mio POM del progetto esplicitamente la versione più alta - 2.8.7 di queste due.

Nelle proprietà:

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

E come dipendenza:

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

2) Ma può anche essere risolto usando Esclusioni di dipendenze.

Con lo stesso principio riportato nell'esempio seguente:

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

La dipendenza con la versione indesiderata verrà esclusa dal tuo progetto.

Se il nome del tuo file è diverso dal nome della classe che contiene il metodo main, è possibile che questo errore possa causare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top