Pergunta

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

Foi útil?

Solução

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

Olhe para o rastreamento de pilha ...Se a exceção aparecer ao chamar um método em um objeto em uma biblioteca, provavelmente você está usando 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 objetos instanciados por classes você feito, então seu processo de construção parece estar com defeito.Certifique-se de que os arquivos de classe que você está realmente executando sejam atualizados durante a compilação.

Outras dicas

Eu estava tendo o seu problema e foi assim que resolvi.As etapas a seguir são uma maneira prática de adicionar uma biblioteca.Eu fiz as duas primeiras etapas corretamente, mas não fiz a última, arrastando o arquivo ".jar" direto do sistema de arquivos para a pasta "lib" no meu projeto Eclipse.Além disso, tive que remover a versão anterior da biblioteca do caminho de construção e da pasta “lib”.

Passo 1 – Adicione .jar ao caminho de construção

enter image description here

Passo 2 – Associar fontes e javadocs (opcional)

enter image description here

Etapa 3 - Arraste o arquivo .jar para a pasta "lib" (não opcional)

enter image description here

Observe que no caso de reflexão, você obtém um NoSuchMethodException, enquanto com código não reflexivo, você obtém NoSuchMethodError.Tenho tendência a procurar lugares muito diferentes quando me deparo com um ou outro.

Se você tiver acesso para alterar os parâmetros da JVM, a adição de saída detalhada deverá permitir que você veja quais classes estão sendo carregadas de quais JARs.

java -verbose:class <other args>

Quando seu programa é executado, a JVM deve despejar informações padronizadas como:

...

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

...

Isso geralmente é causado ao usar um sistema de compilação como Formiga Apache que só compila arquivos java quando o arquivo java é mais recente que o arquivo de classe.Se a assinatura de um método for alterada e as classes estiverem usando a versão antiga, as coisas podem não ser compiladas corretamente.A solução usual é fazer uma reconstrução completa (geralmente "ant clean" e depois "ant").

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

Se estiver usando Maven ou outro framework, e você receber esse erro quase aleatoriamente, tente uma instalação limpa como...

clean install

É especialmente provável que isso funcione se você escreveu o objeto e sabe que ele possui o método.Funcionou para mim.

Isso também pode ser o resultado do uso de reflexão.Se você possui um código que reflete uma classe e extrai um método por nome (por exemplo:com Class.getDeclaredMethod("someMethodName", .....)), sempre que o nome do método for alterado, como durante uma refatoração, você precisará se lembrar de atualizar os parâmetros do método de reflexão para corresponder à nova assinatura do método ou ao getDeclaredMethod chamada lançará um NoSuchMethodException.

Se esse for o motivo, o rastreamento de pilha deverá mostrar o ponto em que o método de reflexão foi invocado e você só precisará atualizar os parâmetros para corresponder à assinatura real do método.

Na minha experiência, isso surge ocasionalmente ao testar métodos/campos privados e usar um TestUtilities classe para extrair campos para verificação de teste.(Geralmente com código legado que não foi projetado tendo em mente o teste de unidade.)

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

por exemplo.

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

Esses problemas são causados ​​pelo uso do mesmo objeto nas mesmas duas classes.Os objetos usados ​​não contêm um novo método que foi adicionado à nova classe de objeto.

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$ 

Esses problemas são causados ​​​​pelas 02 classes semelhantes concomitantes (1 em src, 1 em arquivo jar aqui é gateway.jar)

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

  1. Se você estiver usando jar, descompile e verifique se a respectiva versão do jar possui a classe adequada.
  2. Verifique se você compilou a classe adequada de sua fonte.

Para mim isso aconteceu porque mudei o tipo de argumento na função, de Objeto a para String a.Eu poderia resolver isso limpando e construindo novamente

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

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

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

Apenas adicionando às respostas existentes.Eu estava enfrentando esse problema com o Tomcat no Eclipse.Eu mudei uma classe e segui os seguintes passos,

  1. Limpei e construí o projeto no eclpise

  2. instalação limpa mvn

  3. Gato reiniciado

Ainda assim eu estava enfrentando o mesmo erro.Então Eu limpei o Tomcat, limpei o diretório de trabalho do Tomcat e reiniciei o servidor e meu problema desapareceu.Espero que isso ajude alguém

Corrigi esse problema no Eclipse renomeando um arquivo de teste Junit.
No meu espaço de trabalho Eclipse, tenho um projeto de aplicativo e um projeto de teste.
O projeto Test tem o projeto App como um projeto obrigatório no caminho de construção.

Comecei a receber o NoSuchMethodError.
Então percebi que a classe no projeto Teste tinha o mesmo nome da classe no projeto App.

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

Depois de renomear o teste com o nome correto "ProjectionTest.java", a exceção desapareceu.

Encontrei um problema semelhante quando estava alterando assinaturas de métodos em meu aplicativo.Limpar e reconstruir meu projeto resolveu o “NoSuchMethodError”.

A resposta acima explica muito bem ... apenas para adicionar uma coisa se você estiver usando o uso do Eclipse Use Ctrl+Shift+T e insira a estrutura do pacote da classe (por exemplo:gateway.smpp.PDUEventListener ), você encontrará todos os jars/projetos onde estiver presente.Remova jars desnecessários do caminho de classe ou adicione acima no caminho de classe.Agora ele pegará o correto.

Encontrei um problema semelhante.

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

Finalmente, identifiquei que a causa raiz era a alteração do 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 jar incluindo apenas as classes modificadas.Como não houve alteração ReportGeneration.java Eu estava incluindo apenas o Employee.class no arquivo Jar.Eu tive que incluir o ReportGeneration.class arquivo no jar para resolver o problema.

Eu tive o mesmo problema.Isso também é causado quando há ambigüidade nas classes.Meu programa estava tentando invocar um método que estava presente em dois arquivos JAR presentes no mesmo local/caminho de classe.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 contenham a mesma classe.

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

Para responder à pergunta original.De acordo com documentos java aqui:

"NoSuchMethodError" Lançado se um aplicativo tentar chamar um método especificado de uma classe (estático ou de instância) e essa classe 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 classe tiver sido alterada de forma incompatível.

  1. Se isso acontecer em tempo de execução, verifique se a classe que contém o método está no caminho da classe.
  2. Verifique se você adicionou uma nova versão do JAR e se 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 em tempo de execução, o único motivo poderá ser a mudança na estrutura da classe que o tornou incompatível.

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

Eu também encontrei esse erro.

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

void invest(Currency money){...}

em

void invest(Euro money){...}

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

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

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

O compilador ficou em silêncio em relação a avisos/erros, já que capital é tanto moeda quanto euro.

O problema apareceu devido ao fato de eu ter compilado apenas a classe na qual o método foi definido - Banco, mas não a classe da qual o método está sendo chamado, que contém o método main().

Esse problema não é algo que você possa encontrar com muita frequência, pois na maioria das vezes o projeto é reconstruído manualmente ou uma ação Build é acionada automaticamente, em vez de apenas compilar a classe modificada.

Meu caso de uso foi gerar um arquivo .jar que seria usado como hotfix, que não continha o App.class, pois não foi modificado.Fez sentido para mim não incluí-lo, pois mantive a classe base do argumento inicial por meio da herança.

O problema é que, quando você compila uma classe, o bytecode resultante é uma espécie de estático, em outras palavras, é um referência física.

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

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

Após o ClassLoader carregar o novo Bank.class compilado, ele não encontrará tal método, parece que foi removido e não alterado, daí o erro nomeado.

Espero que isto ajude.

O problema no meu caso foi ter duas versões da mesma biblioteca no caminho de construção.A versão mais antiga da biblioteca não tinha essa função, e a mais recente tinha.

Tive um problema semelhante com meu projeto Gradle usando Intelij.Eu resolvi isso excluindo o pacote .gradle (veja a imagem abaixo) e reconstruindo o projeto.Pacote .gradle

NoSuchMethodError:Passei algumas horas corrigindo esse problema, finalmente corrigi-o apenas renomeando o nome do pacote, limpando e construindo ...Tente a compilação limpa primeiro, se não funcionar, tente renomear o nome da classe ou do pacote e a compilação limpa... ela deve ser corrigida.Boa sorte.

Eu tive o mesmo erro:

  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)

Para resolver verifiquei, primeiramente, Diagrama de dependência de módulo (click in your POM the combination -> Ctrl+Alt+Shift+U ou right click in your POM -> Maven -> Show dependencies) para entender onde exatamente estava o conflito entre bibliotecas (Intelij IDEA).No meu caso particular, eu tinha diferentes versões de dependências de Jackson.

enter image description here enter image description here

1) Então, adicionei diretamente no meu POM do projeto explicitamente a versão mais recente - 2.8.7 dessas duas.

Nas propriedades:

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

E como dependência:

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

2) Mas também pode ser resolvido usando Exclusões de Dependência.

Pelo mesmo princípio abaixo no exemplo:

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

A dependência com versão indesejada será excluída do seu projeto.

Se o nome do seu arquivo for diferente do nome da classe que contém o método principal, pode ser que esse erro possa causar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top