Estou recebendo um NoSuchMethodError
erro ao executar meu programa Java. O que há de errado e como corrigi-lo?
Estou recebendo um NoSuchMethodError
erro ao executar meu programa Java. O que há de errado e como corrigi-lo?
Respostas:
Sem mais informações, é difícil identificar o problema, mas a causa principal é que você provavelmente compilou uma classe com uma versão diferente da classe que está faltando um método, além da que você está usando ao executá-lo.
Observe o rastreamento da pilha ... Se a exceção aparecer ao chamar um método em um objeto em uma biblioteca, é provável que você esteja usando versões separadas da biblioteca ao compilar e executar. Verifique se você tem a versão correta nos dois lugares.
Se a exceção aparecer ao chamar um método em objetos instanciados pelas classes que você criou, seu processo de compilação parece estar com defeito. Verifique se os arquivos de classe que você está realmente executando são atualizados ao compilar.
Caused by
seção no rastreamento de pilha para encontrar a classe / jar
Eu estava tendo seu problema, e foi assim que eu o corrigi. As etapas a seguir são uma maneira prática de adicionar uma biblioteca. Eu tinha feito os dois primeiros passos corretamente, mas não o último, arrastando o arquivo ".jar" diretamente do sistema de arquivos para a pasta "lib" no meu projeto eclipse. Além disso, eu tive que remover a versão anterior da biblioteca do caminho de compilação e da pasta "lib".
Observe que, no caso de reflexão, você recebe um NoSuchMethodException
, enquanto que com código não reflexivo, recebe NoSuchMethodError
. Costumo procurar em lugares muito diferentes quando confrontados com um contra o outro.
Se você tiver acesso para alterar os parâmetros da JVM, a inclusão de saída detalhada deve permitir que você veja quais classes estão sendo carregadas a partir de quais arquivos JAR.
java -verbose:class <other args>
Quando seu programa é executado, a JVM deve despejar para obter informações padronizadas, como:
...
[Junit.framework.Assert carregado do arquivo: / C: /Program%20Files/junit3.8.2/junit.jar]
...
Isso geralmente é causado ao usar um sistema de compilação como o Apache Ant que apenas compila arquivos java quando o arquivo java é mais recente que o arquivo de classe. Se uma assinatura de método for alterada e as classes estiverem usando a versão antiga, as coisas poderão não ser compiladas corretamente. A correção habitual é fazer uma reconstrução completa (geralmente "limpeza de formigas" e depois "formigas").
Às vezes, isso também pode ser causado durante a compilação em uma versão de uma biblioteca, mas em execução em uma versão diferente.
Se você estiver usando o Maven ou outra estrutura, e você receber esse erro quase aleatoriamente, tente uma instalação limpa como ...
clean install
Isso provavelmente funcionará se você escreveu o objeto e sabe que ele possui o método. Trabalhou para mim.
Isso também pode ser o resultado do uso da reflexão. Se você possui um código que reflete em uma classe e extrai um método por nome (por exemplo: with Class.getDeclaredMethod("someMethodName", .....)
), sempre que o nome do método for alterado, como durante um refator, será necessário lembrar de atualizar os parâmetros para o método de reflexão para corresponder ao nova assinatura de método, ou a getDeclaredMethod
chamada lançará a NoSuchMethodException
.
Se esse for o motivo, o rastreamento da pilha deve mostrar o ponto em que o método de reflexão é chamado, e você só precisará atualizar os parâmetros para corresponder à assinatura real do método.
Na minha experiência, isso ocorre ocasionalmente ao testar métodos / campos particulares, e ao usar uma TestUtilities
classe para extrair campos para verificação de teste. (Geralmente, com código herdado que não foi projetado com o teste de unidade em mente.)
Se você estiver escrevendo um aplicativo da Web, verifique se não possui versões conflitantes de um jar no diretório de biblioteca global do contêiner e também no aplicativo. Você pode não necessariamente saber qual jar está sendo usado pelo carregador de classes.
por exemplo
Esses problemas são causados pelo uso do mesmo objeto nas mesmas duas classes. Objetos usados não contém novo método foi adicionado que a nova classe de objeto 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.<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 pela classe similar 02 concomitante (1 no src, 1 no arquivo jar aqui é gateway.jar)
Acabei de solucionar esse erro reiniciando o Eclipse e executando o aplicativo. O motivo do meu caso pode ser porque substituo meus arquivos de origem sem fechar meu projeto ou o Eclipse. O que causou uma versão diferente das classes que eu estava usando.
Tente desta maneira: remova todos os arquivos .class nos diretórios do seu projeto (e, é claro, todos os subdiretórios). Reconstruir.
Às vezes mvn clean
(se você estiver usando o maven) não limpa os 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 as etapas,
Limpou e construiu o projeto em eclpise
instalação limpa do mvn
Ainda estava enfrentando o mesmo erro. Em seguida , 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
Para responder à pergunta original. De acordo com o java docs aqui :
"NoSuchMethodError" Lançado se um aplicativo tentar chamar um método especificado de uma classe (estática ou instância) e essa classe não tiver mais uma definição desse método.
Normalmente, esse erro é detectado pelo compilador; esse erro pode ocorrer apenas em tempo de execução se a definição de uma classe tiver sido alterada incompativelmente.
Corrigi esse problema no Eclipse renomeando um arquivo de teste do Junit.
No meu espaço de trabalho do Eclipse, tenho um projeto App e um projeto Test.
O projeto Teste tem o projeto App como um projeto necessário no caminho da construção.
Começou a obter o NoSuchMethodError.
Então percebi que a classe no projeto Teste tinha o mesmo nome que a 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.
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 resolvê-lo, verifiquei, primeiro, o Diagrama de Dependência do 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 havia o conflito entre as bibliotecas (Intelij IDEA). No meu caso particular, eu tinha versões diferentes das dependências de Jackson.
1) Então, adicionei diretamente no meu POM do projeto explicitamente a versão mais alta - 2.8.7 desses dois.
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 que 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 a versão indesejada será excluída do seu projeto.
No meu caso, eu tinha um projeto com vários módulos e o cenário era como com.xyz.TestClass
estava no módulo A
e assim como no módulo B
e o módulo A
dependia do módulo B
. Então, ao criar um jar de montagem, acho que apenas uma versão da classe foi mantida se esse não tiver o método invocado, então eu estava obtendoNoSuchMethodError
exceção de tempo de execução, mas a compilação estava correta.
Relacionado: https://reflectoring.io/nosuchmethod/
A resposta acima explica muito bem .. apenas para adicionar uma coisa Se você estiver usando o eclipse, use ctrl + shift + T e insira a estrutura de pacotes da classe (por exemplo: gateway.smpp.PDUEventListener), você encontrará todos os jars / projetos onde está presente . Remova os jarros desnecessários do caminho de classe ou adicione acima no caminho da classe. Agora ele pegará o correto.
Eu tive um problema semelhante.
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
Finalmente, identifiquei que a causa raiz estava mudando o tipo de dados da variável.
Employee.java
-> Contém a variável ( EmpId
) cujo Tipo de Dados foi alterado de int
para String
.ReportGeneration.java
-> Recupera o valor usando o getter getEmpId()
,.Devemos reorganizar o jar incluindo apenas as classes modificadas. Como não houve alteração, ReportGeneration.java
eu estava apenas incluindo o Employee.class
arquivo Jar. Eu tive que incluir o ReportGeneration.class
arquivo no frasco para resolver o problema.
Eu tive o mesmo problema. Isso também é causado quando há uma ambiguidade nas classes. Meu programa estava tentando chamar um método que estava presente em dois arquivos JAR presentes no mesmo caminho de local / classe. Exclua um arquivo JAR ou execute seu código para 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 classe.
DISP_E_EXCEPTION [etapa] [] [Exceção Java Z-JAVA-105 java.lang.NoSuchMethodError (com.example.yourmethod)]
Na maioria das vezes, o java.lang.NoSuchMethodError é capturado no compilador, mas às vezes pode ocorrer em tempo de execução. Se esse erro ocorrer no tempo de execução, o único motivo pode ser a alteração na estrutura da classe que o tornou incompatível.
Melhor explicação: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
Também encontrei este erro.
Meu problema era que alterei a assinatura de um método, algo como
void invest(Currency money){...}
para dentro
void invest(Euro money){...}
Este método foi chamado 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 em silêncio em relação a avisos / erros, pois o capital é tanto moeda quanto euro.
O problema apareceu devido ao fato de eu compilar apenas a classe na qual o método foi definido - Bank, 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ê pode encontrar com muita frequência, pois na maioria das vezes o projeto é reconstruído manualmente ou uma ação de compilação é acionada automaticamente, em vez de apenas compilar a classe modificada.
Meu caso de usuário foi que eu gerei um arquivo .jar que deveria ser usado como um hotfix, que não continha o App.class, pois isso não foi modificado. Fazia sentido não incluí-lo, pois mantinha a classe base do argumento inicial através da herança.
O problema é que, quando você compila uma classe, o bytecode resultante é meio estático , em outras palavras, é um referência rígida .
O bytecode desmontado original (gerado com a ferramenta javap) fica assim:
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
Depois que o ClassLoader carrega o novo Bank.class compilado, ele não encontra esse método, parece que ele foi removido e não foi alterado, portanto, o erro nomeado.
Espero que isto ajude.
Eu tive um problema semelhante com meu projeto Gradle usando Intelij. Eu o resolvi excluindo o pacote .gradle (veja a captura de tela abaixo) e reconstruindo o projeto. Pacote .gradle
NoSuchMethodError: Passei algumas horas corrigindo esse problema, finalmente o corrigi apenas renomeando o nome do pacote, limpo e compilado ... Tente a compilação limpa primeiro, se não funcionar, tente renomear o nome da classe ou o nome do pacote e a compilação limpa. . deve ser corrigido. Boa sorte.
Se o nome do seu arquivo for diferente do nome da classe que contém o método principal, é possível que esse erro possa causar.