Estou recebendo um NoClassDefFoundError
quando executo meu aplicativo Java. Qual é tipicamente a causa disso?
java
noclassdeffounderror
John Meagher
fonte
fonte
Respostas:
Isso é causado quando há um arquivo de classe do qual seu código depende e está presente no tempo de compilação, mas não encontrado no tempo de execução. Procure diferenças no tempo de construção e nos caminhos de classe do tempo de execução.
fonte
Embora seja possível que isso ocorra devido a uma incompatibilidade de caminho de classe entre o tempo de compilação e o tempo de execução, isso não é necessariamente verdade.
É importante manter duas ou três exceções diferentes em mente neste caso:
java.lang.ClassNotFoundException
Essa exceção indica que a classe não foi encontrada no caminho de classe. Isso indica que estávamos tentando carregar a definição de classe e a classe não existia no caminho de classe.java.lang.NoClassDefFoundError
Essa exceção indica que a JVM procurou em sua estrutura de dados de definição de classe interna a definição de uma classe e não a encontrou. Isso é diferente de dizer que não foi possível carregar o caminho de classe. Normalmente, isso indica que anteriormente tentamos carregar uma classe do caminho de classe, mas ela falhou por algum motivo - agora estamos tentando usar a classe novamente (e, portanto, precisamos carregá-la, pois ela falhou da última vez), mas nós ' nem vamos tentar carregá-lo, porque falhamos ao carregá-lo mais cedo (e suspeitamos razoavelmente que falharíamos novamente). A falha anterior pode ser um ClassNotFoundException ou um ExceptionInInitializerError (indicando uma falha no bloco de inicialização estática) ou qualquer número de outros problemas. O ponto é que um NoClassDefFoundError não é necessariamente um problema de caminho de classe.fonte
Error: Could not find or load main class
, ele será classificado em qual categoria de erro?Aqui está o código para ilustrar
java.lang.NoClassDefFoundError
. Por favor, veja a resposta de Jared para uma explicação detalhada.NoClassDefFoundErrorDemo.java
SimpleCalculator.java
fonte
SimpleCalculator
após a divisão por zero? Alguém tem uma referência à documentação oficial para esse comportamento?new SimpleCalculator()
você chama, você obtém um ExceptionInInitializerError causado por ArithmeticException. Na segunda vez que você liga,new SimpleCalculator()
você obtém um NoClassDefFoundError tão puro quanto qualquer outro. O ponto é que você pode obter um NoClassDefFoundError por um motivo diferente de SimpleCalculator.class que não esteja no caminho de classe no tempo de execução.NoClassDefFoundError em Java
Definição:
O Java Virtual Machine não consegue encontrar uma classe específica em tempo de execução que estava disponível no momento da compilação.
Se uma classe estava presente durante o tempo de compilação, mas não estava disponível no caminho de classe java durante o tempo de execução.
Exemplos:
Um exemplo simples de NoClassDefFoundError is class pertence a um arquivo JAR ausente ou o JAR não foi adicionado ao caminho de classe ou, às vezes, o nome do jar foi alterado por alguém como no meu caso, um dos meus colegas alterou tibco.jar para tibco_v3.jar e o programa é falhando com java.lang.NoClassDefFoundError e eu queria saber o que há de errado.
Apenas tente executar com a opção explicitamente -classpath com o caminho de classe que você acha que funcionará e, se estiver funcionando, é um pequeno sinal claro de que alguém está substituindo o caminho de classe java.
Soluções possíveis:
Recursos:
3 maneiras de resolver NoClassDefFoundError
java.lang.NoClassDefFoundError Padrões de problemas
fonte
Descobri que às vezes recebo um erro NoClassDefFound quando o código é compilado com uma versão incompatível da classe encontrada no tempo de execução. A instância específica que me lembro é da biblioteca de eixos apache. Na verdade, havia duas versões no meu caminho de classe em tempo de execução e ele pegava a versão desatualizada e incompatível e não a correta, causando um erro NoClassDefFound. Isso estava em um aplicativo de linha de comando em que eu estava usando um comando semelhante a este.
Consegui fazê-lo pegar a versão correta usando:
fonte
Esta é a melhor solução que encontrei até agora.
Suponha que tenhamos um pacote chamado
org.mypackage
contendo as classes:e os arquivos que definem este pacote são armazenados fisicamente no diretório
D:\myprogram
(no Windows) ou/home/user/myprogram
(no Linux).A estrutura do arquivo ficará assim:
Quando invocamos Java, que especifique o nome do aplicativo para executar:
org.mypackage.HelloWorld
. No entanto, também devemos informar ao Java onde procurar os arquivos e diretórios que definem nosso pacote. Então, para iniciar o programa, precisamos usar o seguinte comando:fonte
Eu estava usando o Spring Framework com o Maven e resolvi esse erro no meu projeto.
Houve um erro de tempo de execução na classe. Eu estava lendo uma propriedade como número inteiro, mas quando leu o valor do arquivo de propriedades, seu valor foi duplo.
O Spring não me deu um rastreamento completo da pilha em qual linha o tempo de execução falhou. Simplesmente disse
NoClassDefFoundError
. Mas quando eu o executei como um aplicativo Java nativo (removendo-o do MVC), ele forneceuExceptionInInitializerError
qual era a causa verdadeira e qual foi a maneira como eu rastreei o erro.A resposta da @ xli me deu uma ideia do que pode estar errado no meu código.
fonte
NoClassDefFoundError
na verdade, foi causado porExceptionInInitalizerError
, o que foi causado porDateTimeParseException
). É um pouco enganador, não é? Eu sei que eles provavelmente tiveram suas razões para fazer dessa maneira, mas seria muito bom ter pelo menos uma pequena dica, queNoClassDefFoundError
foi o resultado de outra exceção, sem a necessidade de deduzi-la. Apenas jogar deExceptionInInitializerError
novo seria muito mais claro. Às vezes, a conexão entre os dois pode não ser tão óbvia.Recebo NoClassFoundError quando as classes carregadas pelo carregador de classes de tempo de execução não podem acessar as classes já carregadas pelo java rootloader. Como os diferentes carregadores de classes estão em domínios de segurança diferentes (de acordo com java), a jvm não permitirá que as classes já carregadas pelo rootloader sejam resolvidas no espaço de endereço do carregador de tempo de execução.
Execute seu programa com 'java -javaagent: tracer.jar [YOUR java ARGS]'
Produz saída mostrando a classe carregada e o env do carregador que carregou a classe. É muito útil rastrear por que uma classe não pode ser resolvida.
fonte
Um caso interessante no qual você pode ver muitos
NoClassDefFoundErrors
é quando:throw
umRuntimeException
nostatic
bloco da sua turmaExample
Example
NoClassDefError
será lançado acompanhadoExceptionInInitializerError
pelo bloco estáticoRuntimeException
.Este é um caso especialmente importante quando você vê
NoClassDefFoundErrors
seus TESTES UNITÁRIOS .De certa forma, você está "compartilhando" a
static
execução do bloco entre os testes, mas a inicialExceptionInInitializerError
será apenas em um caso de teste. O primeiro que usa aExample
classe problemática . Outros casos de teste que usam aExample
classe serão lançadosNoClassDefFoundErrors
.fonte
A técnica abaixo me ajudou muitas vezes:
onde TheNoDefFoundClass é a classe que pode ser "perdida" devido a uma preferência por uma versão mais antiga da mesma biblioteca usada pelo seu programa. Isso ocorre com mais freqüência nos casos em que o software cliente está sendo implantado em um contêiner dominante, armado com seus próprios carregadores de classes e toneladas de versões antigas das bibliotecas mais populares.
fonte
Caso você tenha gerado código (EMF, etc.), pode haver muitos inicializadores estáticos que consomem todo o espaço da pilha.
Consulte a pergunta Estouro de pilha Como aumentar o tamanho da pilha Java? .
fonte
Corrigi o meu problema desativando as preDexLibraries para todos os módulos:
fonte
NoClassDefFoundError
também pode ocorrer quando um inicializador estático tenta carregar um pacote configurável de recursos que não está disponível em tempo de execução, por exemplo, um arquivo de propriedades que a classe afetada tenta carregar doMETA-INF
diretório, mas não existe. Se você não capturarNoClassDefFoundError
, às vezes não poderá ver o rastreamento completo da pilha; Para superar isso, você pode usar temporariamente umacatch
cláusula paraThrowable
:fonte
for example a properties file that the affected class tries to load from the META-INF directory
. Isso realmente aconteceu comigo e eu pude resolver issoNoClassDefFoundError
adicionando o arquivo de propriedades que estava faltando. Eu adicionei esta resposta exatamente porque não se esperaria esse erro nas circunstâncias mencionadas.static
inicialização ... o que acionou uma exceção não verificada e causou a classe init falhar. Qualquer exceção desmarcada propagada da inicialização estática faria isso.static
inicialização), eu estaria interessado em ver um exemplo real (isto é, um MCVE) que demonstra o comportamento.Eu recebi esse erro ao adicionar a dependência do Maven de outro módulo ao meu projeto, o problema foi finalmente resolvido com a adição
-Xss2m
da opção JVM do meu programa (é um megabyte por padrão desde o JDK5.0). Acredita-se que o programa não tenha pilha suficiente para carregar a classe.fonte
Se alguém vier aqui por causa de
java.lang.NoClassDefFoundError: org/apache/log4j/Logger
erro, no meu caso, foi produzido porque usei o log4j 2 (mas não adicionei todos os arquivos que o acompanham) e alguma biblioteca de dependência utilizou o log4j 1. A solução foi adicionar o Log4j 1.x bridge: o jarlog4j-1.2-api-<version>.jar
que acompanha o log4j 2. Mais informações na migração do log4j 2 .fonte
Duas cópias diferentes do checkout do mesmo projeto
No meu caso, o problema era a incapacidade do Eclipse de diferenciar entre duas cópias diferentes do mesmo projeto. Eu tenho um bloqueado no tronco (controle de versão SVN) e o outro trabalhando em uma ramificação por vez. Tentei uma alteração na cópia de trabalho como um caso de teste JUnit, que incluía extrair uma classe interna privada para ser uma classe pública por conta própria e enquanto ele estava funcionando, abro a outra cópia do projeto para procurar outras parte do código que precisava de alterações. Em algum momento, o grupo
NoClassDefFoundError
apareceu reclamando que a classe interna privada não estava lá; clicar duas vezes no rastreamento da pilha levou-me ao arquivo de origem na cópia incorreta do projeto.Fechar a cópia de tronco do projeto e executar o caso de teste novamente se livrou do problema.
fonte
Este erro pode ser causado por requisitos de versão Java não verificados .
No meu caso, consegui resolver esse erro, ao criar um projeto de código aberto de alto perfil, alternando do Java 9 para o Java 8 usando o SDKMAN! .
Em seguida, faça uma instalação limpa, conforme descrito abaixo.
Ao usar o Maven como sua ferramenta de criação, às vezes é útil - e geralmente gratificante, fazer uma compilação limpa de 'instalação' com o teste desativado .
Agora que tudo foi construído e instalado, você pode prosseguir e executar os testes.
fonte
Eu recebi erros NoClassDefFound quando não exportei uma classe na guia "Ordem e exportação" no caminho de compilação Java do meu projeto. Certifique-se de marcar a guia "Ordem e exportação" de todas as dependências adicionadas ao caminho de criação do projeto. Consulte Aviso do Eclipse: XXXXXXXXXXX.jar não será exportado ou publicado. O tempo de execução ClassNotFoundExceptions pode resultar .
fonte
Também pode ser porque você copia o arquivo de código de um IDE com um determinado nome de pacote e deseja tentar executá-lo usando o terminal. Você precisará remover o nome do pacote do código primeiro. Isso acontece comigo.
fonte
No meu caso, eu estava recebendo esse erro devido a uma incompatibilidade nas versões do JDK. Quando tentei executar o aplicativo da Intelij, ele não estava funcionando, mas funcionou na linha de comando. Isso ocorre porque o Intelij estava tentando executá-lo com o Java 11 JDK que estava configurado, mas na linha de comando estava em execução com o Java 8 JDK. Depois de alternar essa configuração em Arquivo> Estrutura do projeto> Configurações do projeto> SDK do projeto, funcionou para mim.
fonte
Todo mundo fala aqui sobre algumas coisas de configuração Java, problemas de JVM etc., no meu caso, o erro não estava relacionado a esses tópicos e tinha uma razão muito trivial e fácil de resolver: eu tinha uma anotação errada no meu endpoint no meu Controller ( Aplicativo Spring Boot).
fonte
Eu tive um problema interessante com o NoClassDefFoundError no JavaEE, trabalhando com o servidor Liberty. Eu estava usando adaptadores de recursos IMS e meu server.xml já tinha um adaptador de recursos para imsudbJXA.rar. Quando adicionei um novo adaptador para imsudbXA.rar, eu começava a receber esse erro para objetos de instância para DLIException, IMSConnectionSpec ou SQLInteractionSpec. Não consegui entender o motivo, mas resolvi criando um novo server.xml para o meu trabalho usando apenas imsudbXA.rar. Estou certo de que o uso de vários adaptadores de recursos no server.xml é bom, mas não tive tempo de analisar isso.
fonte
Java não conseguiu encontrar a classe A em tempo de execução. A Classe A estava no projeto ArtClient de um novo espaço de trabalho. Portanto, importei o ArtClient para o meu projeto Eclipse. Dois dos meus projetos estavam usando o ArtClient como dependência. Alterei a referência da biblioteca para a referência do projeto para esses (Build Path -> Configure Build Path).
E o problema foi embora.
fonte
Eu tive o mesmo problema e fiquei em estoque por muitas horas.
Eu encontrei a solução. No meu caso, havia o método estático definido devido a isso. A JVM não pode criar o outro objeto dessa classe.
Por exemplo,
fonte
Recebi essa mensagem depois de remover dois arquivos da biblioteca SRC e, quando os trouxe de volta, continuei vendo essa mensagem de erro.
Minha solução foi: Reinicie o Eclipse. Desde então, eu não vi essa mensagem novamente :-)
fonte
Verifique se isso corresponde ao
module:app
emodule:lib
:fonte
{s
e dois}
). Consegues consertar isso?