Como corrijo um NoSuchMethodError?

Estou recebendo um erro NoSuchMethodError ao executar meu programa Java. O que há de errado e como faço para corrigir isso?

    Sem mais informações, é difícil identificar o problema, mas a causa raiz é que você provavelmente compilou uma class contra uma versão diferente da class que está faltando um método, do que aquele que você está usando ao executá-lo.

    Observe o rastreio de pilha … Se a exceção aparecer ao chamar um método em um object em uma biblioteca, você provavelmente usará versões separadas da biblioteca ao compilar e executar. Certifique-se de ter a versão correta em ambos os lugares.

    Se a exceção aparecer ao chamar um método em objects instanciados por classs que você criou, seu processo de compilation parece estar com defeito. Verifique se os arquivos de class que você está executando realmente são atualizados quando você compila.

    Eu sinto sua dor. Você pode aprender a programar em um livro, mas quando se trata de trabalhar com o Eclipse ou o Visual Studio, é um pesadelo para fazer algo simples, como adicionar uma biblioteca. Todo mundo espera que você saiba como usá-lo e, se você não o fizer, sua pergunta será rejeitada. O problema é que, se você não trabalha em um escritório ou conhece alguém que possa fazer essas perguntas, é quase impossível descobrir essas coisas. De qualquer forma…

    Eu estava tendo seu problema, e foi assim que eu consertei. As etapas a seguir são uma maneira prática de adicionar uma biblioteca. Eu tinha feito os dois primeiros passos certos, mas eu não tinha feito o último arrastando o arquivo “.jar” direto do sistema de arquivos para a pasta “lib” no meu projeto eclipse. Além disso, precisei remover a versão anterior da biblioteca do caminho de construção e da pasta “lib”.

    Se alguém souber de uma maneira mais adequada de adicionar / atualizar uma biblioteca, entre em contato.

    Etapa 1 – Adicionar .jar para construir caminho

    insira a descrição da imagem aqui

    Etapa 2 – fonts associadas e javadocs (opcional)

    insira a descrição da imagem aqui

    Passo 3 – Realmente arraste o arquivo .jar para a pasta “lib” (não opcional)

    insira a descrição da imagem aqui

    Observe que, no caso de reflection, você obtém uma NoSuchMethodException , enquanto com código não reflexivo, obtém NoSuchMethodError . Eu costumo olhar em lugares muito diferentes quando confrontados com um versus o outro.

    Se você tiver access para alterar os parâmetros da JVM, include a saída detalhada deverá permitir ver quais classs estão sendo carregadas de quais JARs.

     java -verbose:class  

    Quando seu programa é executado, a JVM deve descarregar para informações padrão, como:

    [Loaded junit.framework.Assert do arquivo: / C: /Program%20Files/junit3.8.2/junit.jar]

    Isso geralmente é causado ao usar um sistema de compilation como o Apache Ant, que apenas compila arquivos java quando o arquivo java é mais novo que o arquivo de class. Se uma assinatura de método mudar e as classs estiverem usando a versão antiga, as coisas podem não ser compiladas corretamente. A correção usual é fazer uma reconstrução completa (geralmente “formiga limpa” e “formiga”).

    Às vezes, isso também pode ser causado ao compilar em uma versão de uma biblioteca, mas em uma versão diferente.

    Isso também pode ser o resultado do uso da reflection. Se você tiver código que reflita em uma class e extraia um método por nome (por exemplo: com Class.getDeclaredMethod("someMethodName", .....) ), a qualquer momento que o nome do método for alterado, como durante um refator, você Lembre-se de atualizar os parâmetros para o método de reflection para coincidir com a assinatura do novo método, ou a chamada getDeclaredMethod lançará uma NoSuchMethodException .

    Se esse for o motivo, o rastreamento de pilha deve mostrar o ponto em que o método de reflection é chamado e você precisará apenas atualizar os parâmetros para corresponder à assinatura do método real.

    Na minha experiência, isso ocorre ocasionalmente quando a unidade testa methods / campos privados e usa uma class TestUtilities para extrair campos para verificação de teste. (Geralmente com código legado que não foi projetado com o teste de unidade em mente.)

    Se estiver usando maven ou outra estrutura, e você obter este erro quase aleatoriamente, tente “clean install”, especialmente se você escreveu o object e você sabe que ele tem o método. Trabalhou para mim.

    Se você estiver escrevendo um webapp, certifique-se de não ter versões conflitantes de um jar no diretório global da biblioteca do contêiner e também no seu aplicativo. Você pode não necessariamente saber qual jar está sendo usado pelo classloader.

    por exemplo

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

    Esses problemas são causados ​​pelo uso do mesmo object nas mesmas duas classs. Os objects usados ​​não contêm um novo método que a nova class de object contém.

    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.(Lgateway/smpp/USSDClient;)V at gateway.smpp.USSDClient.bind(USSDClient.java:139) at gateway.USSDGW.initSmppConnection(USSDGW.java:274) at gateway.USSDGW.(USSDGW.java:184) at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40) -bash-3.00$ 

    Estes problemas são causados ​​pela concomitante 02 class similar (1 em src, 1 no arquivo jar aqui é gateway.jar)

    Isso significa que o respectivo método não está presente na class:

    1. Se você estiver usando o jar, decompile e verifique se a respectiva versão do jar tem class apropriada.
    2. Verifique se você compilou a class apropriada de sua fonte.

    Para mim, aconteceu porque mudei o tipo de argumento em function, do Objeto a, para String a. Eu poderia resolvê-lo com limpeza e construir novamente

    Acabei de resolver esse erro reiniciando meu Eclipse e executei o applcation. A razão para o meu caso pode ser porque eu substituo meus arquivos de origem sem fechar meu projeto ou o Eclipse. O que causou uma versão diferente das classs que eu estava usando.

    Tente desta forma: remova todos os arquivos .class sob seus diretórios de projeto (e, é claro, todos os subdiretórios). Reconstruir.

    Às vezes, mvn clean (se você estiver usando maven) não limpa arquivos .class criados manualmente pelo javac . E esses arquivos antigos contêm assinaturas antigas, levando ao NoSuchMethodError .

    Eu tive um problema semelhante quando estava mudando as assinaturas de methods no meu aplicativo. Limpar e reconstruir meu projeto resolveu o “NoSuchMethodError”.

    Acima resposta explica muito bem .. apenas para adicionar uma coisa Se você estiver usando usando eclipse use ctrl + shift + T e digite estrutura do pacote de class (por exemplo: gateway.smpp.PDUEventListener), você encontrará todos os jars / projetos onde está presente . Remova os jars desnecessários do caminho de class ou adicione acima no caminho da class. Agora vai pegar um correto.

    Eu encontrei um problema semelhante.

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

    Finalmente eu identifiquei a causa raiz que estava mudando o tipo de dados da variável.

    1. Employee.java -> Contém a variável ( EmpId ) cujo tipo de dados foi alterado de int para String .
    2. ReportGeneration.java -> Recupera o valor usando o getter, getEmpId() .

    Devemos reagrupar o jarro, incluindo apenas as classs modificadas. Como não houve alteração no ReportGeneration.java eu estava incluindo apenas o arquivo Employee.class in Jar. Eu tive que include o arquivo ReportGeneration.class no jar para resolver o problema.

    Eu tive o mesmo problema. Isso também é causado quando há uma ambigüidade nas classs. Meu programa estava tentando invocar um método que estava presente em dois arquivos JAR presentes no mesmo caminho de localização / class. Exclua um arquivo JAR ou execute seu código de forma que apenas um arquivo JAR seja usado. Verifique se você não está usando o mesmo JAR ou versões diferentes do mesmo JAR que contêm a mesma class.

    DISP_E_EXCEPTION [step] [] [Z-JAVA-105 Java exceção java.lang.NoSuchMethodError (com.example.yourmethod)]

    Para responder a pergunta original. De acordo com o java docs aqui :

    “NoSuchMethodError” Lançada se um aplicativo tentar chamar um método especificado de uma class (estática ou instância) e essa class não tiver mais uma definição desse método.

    Normalmente, esse erro é detectado pelo compilador; esse erro só pode ocorrer em tempo de execução se a definição de uma class tiver alterado de forma incompatível.

    1. Se isso acontecer no tempo de execução, verifique a class que contém o método no caminho da class.
    2. Verifique se você adicionou nova versão do JAR e o método é compatível.

    Na maioria das vezes, java.lang.NoSuchMethodError é capturado pelo compilador, mas às vezes pode ocorrer em tempo de execução. Se esse erro ocorrer no tempo de execução, o único motivo poderá ser a alteração na estrutura de classs que o tornou incompatível.

    Melhor explicação: https://www.journaldev.com/14538/java-lang-nosuchmethoderror

    Eu também encontrei esse erro.

    Meu problema era que eu mudei a assinatura de um método, algo como

     void invest(Currency money){...} 

    para dentro

     void invest(Euro money){...} 

    Este método foi invocado a partir de um contexto semelhante ao

     public static void main(String args[]) { Bank myBank = new Bank(); Euro capital = new Euro(); myBank.invest(capital); } 

    O compilador ficou calado em relação a avisos / erros, já que o capital é tanto Moeda quanto Euro.

    O problema apareceu devido ao fato de que eu apenas compilei a class na qual o método foi definido – Bank, mas não a class da qual o método está sendo chamado, que contém o método main ().

    Esse problema não é algo que você pode encontrar com muita frequência, pois, com mais frequência, o projeto é recriado manualmente ou uma ação Build é acionada automaticamente, em vez de apenas compilar a class modificada.

    Meu usecase foi que eu criei um arquivo .jar que deveria ser usado como um hotfix, que não continha o App.class, pois isso não foi modificado. Não fazia sentido para mim incluí-lo, pois mantive a class base do argumento inicial através da inheritance.

    A coisa é, quando você compila uma class, o bytecode resultante é um pouco estático , em outras palavras, é uma referência difícil .

    O bytecode original desmontado (gerado com a ferramenta javap) é assim:

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

    Depois que o ClassLoader carregar o novo Bank.class compilado, ele não encontrará esse método, ele aparecerá como se tivesse sido removido e não tenha sido alterado, portanto, o erro nomeado.

    Espero que isto ajude.

    Eu consertei esse problema no Eclipse renomeando um arquivo de teste do Junit.
    No meu espaço de trabalho do Eclipse, tenho um projeto de aplicativo e um projeto de teste.
    O projeto de teste tem o projeto de aplicativo como um projeto necessário no caminho de compilation.

    Começou a receber o NoSuchMethodError.
    Então percebi que a turma no projeto Test tinha o mesmo nome da turma do projeto App.

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

    Depois de renomear o teste para o nome correto “ProjectionTest.java” a exceção foi embora.

    Se o seu nome de arquivo for diferente do nome da class que contém o método main, então pode ser a possibilidade que esse erro possa causar.