Pergunta

Eu estou começando uma NoClassDefFoundError quando eu executar a minha aplicação Java.O que normalmente é a causa de tudo isso?

Foi útil?

Solução

Isso é causado quando não há um arquivo de classe que o seu código depende, e está presente em tempo de compilação, mas não achei em tempo de execução.Olhar para as diferenças no tempo de compilação e tempo de execução de classpaths.

Outras dicas

É possível que isto é devido a um classpath incompatibilidade entre o tempo de compilação e tempo de execução, não é necessariamente verdadeiro.

É importante manter duas ou três exceções em linha reta, na nossa cabeça, neste caso:

  1. java.lang.ClassNotFoundException Essa exceção indica que a classe não foi encontrada no classpath.Isso indica que estávamos tentando carregar a definição de classe, e a classe não existe no classpath.

  2. java.lang.NoClassDefFoundError Essa exceção indica que a JVM olhou em sua classe interna definição de estrutura de dados para a definição de uma classe e não a encontrou.Isso é diferente de dizer que ele não pode ser carregado a partir do classpath.Normalmente, isto indica que nós já tentou carregar uma classe de classpath, mas ele falhou por algum motivo, agora estamos tentando usar a classe novamente (e, portanto, precisa carregá-lo, desde que ele falhou última vez), mas nós não estamos indo mesmo para tentar carregá-lo, porque não conseguimos carregar anteriores (e razoavelmente suspeitar de que iria falhar novamente).O anterior falha poderia ser uma ClassNotFoundException ou um ExceptionInInitializerError (indicando uma falha na inicialização estática bloco) ou qualquer número de outros problemas.O ponto é, um NoClassDefFoundError não é necessariamente um classpath problema.

Aqui está o código para ilustrar java.lang.NoClassDefFoundError.Por favor, consulte Jared resposta para uma explicação detalhada.

NoClassDefFoundErrorDemo.java

public class NoClassDefFoundErrorDemo {
    public static void main(String[] args) {
        try {
            // The following line would throw ExceptionInInitializerError
            SimpleCalculator calculator1 = new SimpleCalculator();
        } catch (Throwable t) {
            System.out.println(t);
        }
        // The following line would cause NoClassDefFoundError
        SimpleCalculator calculator2 = new SimpleCalculator();
    }

}

SimpleCalculator.java

public class SimpleCalculator {
    static int undefined = 1 / 0;
}

Eu descobri que às vezes eu fico um NoClassDefFound de erro quando o código é compilado com uma versão incompatível do classe encontrado em tempo de execução.O caso específico que eu lembro é com o apache axis biblioteca.Na verdade, houve 2 versões no meu classpath de tempo de execução e foi pegar o fora de data e versão incompatível e não o correto, causando um NoClassDefFound erro.Isso foi em um aplicativo de linha de comando onde eu estava usando um comando semelhante a esta.

set classpath=%classpath%;axis.jar

Eu era capaz de fazê-lo pegar a versão apropriada usando:

set classpath=axis.jar;%classpath%;

NoClassDefFoundError Em Java

Definição:

  1. A Máquina Virtual Java não é capaz de encontrar uma determinada classe em tempo de execução, que estava disponível em tempo de compilação.

  2. Se uma classe estava presente durante o tempo de compilação, mas não está disponível no classpath java em tempo de execução.

enter image description here

Exemplos:

  1. A classe não está no Classpath, não há certeza de tiro maneira de saber isso, mas muitas vezes você pode ter apenas um olhar para o Sistema de impressão.getproperty("java.classpath") e ele irá imprimir o classpath de lá, você pode pelo menos ter uma idéia de seu classpath de tempo de execução real.
  2. Um exemplo simples de NoClassDefFoundError é de classe pertence à falta de um arquivo JAR ou do FRASCO não foi adicionado ao classpath ou, às vezes, jar do nome foi mudado por alguém, como no meu caso, um dos meus colegas foi alterado tibco.jar em tibco_v3.jar e o programa está falhando com java.lang.NoClassDefFoundError e eu estava me perguntando o que está errado.

  3. Tente apenas executar com explicitamente -classpath opção com o classpath você acha que vai funcionar e se funcionar, então, a uma curta sinal de que alguém está substituindo java classpath.

  4. Problema de permissão no arquivo JAR pode também causar NoClassDefFoundError em Java.
  5. Erro de digitação no XML de Configuração também pode causar NoClassDefFoundError em Java.
  6. quando compilado classe que é definida em um pacote, não presente no mesmo pacote durante o carregamento, como no caso de JApplet ele vai jogar NoClassDefFoundError em Java.

Possíveis Soluções:

  1. A classe não está disponível em Java Classpath.
  2. Se você estiver trabalhando em ambiente J2EE que a visibilidade de Classe entre vários carregador de classe também podem causar java.lang.NoClassDefFoundError, ver exemplos e secção cenário para uma discussão detalhada.
  3. Seleção para java.lang.ExceptionInInitializerError no seu arquivo de log.NoClassDefFoundError devido à falha de inicialização estática é bastante comum.
  4. Porque NoClassDefFoundError é uma subclasse de java.lang.LinkageError ele também pode vir se um de dependência como nativo da biblioteca poderão não estar disponíveis.
  5. Qualquer script de inicialização substituindo a variável de ambiente Classpath.
  6. Você pode estar executando o seu programa usando o comando jar e classe não foi definido no arquivo de manifesto do ClassPath do atributo.

Recursos:

3 maneiras de resolver NoClassDefFoundError

o java.lang.NoClassDefFoundError Problema padrões

Este é o melhor solução Eu encontrei até agora.

Suponha que nós temos um pacote chamado org.mypackage contém as classes:

  • HelloWorld (classe principal)
  • SupportClass
  • UtilClass

e os arquivos de definição do pacote são armazenados fisicamente sob o diretório D:\myprogram (no Windows) ou /home/user/myprogram (no Linux).

A estrutura do arquivo será parecido com este:enter image description here

Quando nós invocamos Java, temos de especificar o nome do aplicativo para executar: org.mypackage.HelloWorld.No entanto, devemos também dizer Java para onde olhar para os arquivos e diretórios a definição do pacote.Então, para iniciar o programa, temos que usar o seguinte comando:enter image description here

Eu estava usando Spring Framework com Maven e resolveu esse erro no meu projeto.

Houve um erro de tempo de execução na classe.Eu estava lendo uma propriedade como inteiro, mas quando ler o valor da propriedade do arquivo, o seu valor era o dobro.

Primavera não me daria um total de rastreio de pilha de em qual linha o tempo de execução falha.Ele simplesmente disse: NoClassDefFoundError.Mas quando eu executado como um nativo aplicação Java (tirando-o do MVC), ele deu ExceptionInInitializerError qual foi a verdadeira causa e o que é como eu traçou o erro.

@xli a resposta me deu uma visão sobre o que pode estar errado no meu código.

Eu fico NoClassFoundError quando as classes carregadas pelo tempo de execução do carregador de classe não podem acessar aulas já carregado pelo java rootloader.Porque as diferentes classes carregadores estão em diferentes domínios de segurança (de acordo com o java, a jvm não permitem que as classes já carregado pelo rootloader para ser resolvido no tempo de execução do carregador de espaço de endereço.

Executar o programa com 'java -javaagent:tracer.jar [java ARGS]'

Ele produz uma saída mostrando carregado de classe, e o carregador env que carregar a classe.É muito útil rastreamento por que uma classe não pode ser resolvido.

// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5

import java.lang.instrument.*;
import java.security.*;

// manifest.mf
// Premain-Class: ClassLoadTracer

// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class

// java -javaagent:tracer.jar  [...]

public class ClassLoadTracer 
{
    public static void premain(String agentArgs, Instrumentation inst) 
    {
        final java.io.PrintStream out = System.out;
        inst.addTransformer(new ClassFileTransformer() {
            public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

                String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
                out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);

                // dump stack trace of the thread loading class 
                Thread.dumpStack();

                // we just want the original .class bytes to be loaded!
                // we are not instrumenting it...
                return null;
            }
        });
    }
}

Leia isso, especialmente se você ver NoClassDefFoundErrors em TESTES de UNIDADE...


Um caso interessante em que você pode ver um monte de NoClassDefFoundErrors é quando você:

  1. throw um RuntimeException no static bloco da classe Example
  2. Interceptá-lo (ou se simplesmente não importa como ele é jogado em um caso de teste)
  3. Tenta criar uma instância dessa classe Example

static class Example {
    static {
        thisThrowsRuntimeException();
    }
}

static class OuterClazz {

    OuterClazz() {
        try {
            new Example();
        } catch (Throwable ignored) { //simulating catching RuntimeException from static block
            // DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
        }

        new Example(); //this throws NoClassDefFoundError
    }
}

NoClassDefError será lançada acompanhado com ExceptionInInitializerError a partir do bloco estático RuntimeException.


Isto é especialmente importante caso quando você ver NoClassDefFoundErrors em seu TESTES DE UNIDADE.

Em uma maneira que você é "compartilhar" o static bloco de execução de testes, mas o inicial ExceptionInInitializerError serão apenas de um caso de teste.O primeiro que usa a problemática Example de classe.Outros casos de teste que usar o Example classe só vai jogar NoClassDefFoundErrors.

No caso de você ter gerado-código (EMF, etc.) pode haver muitas inicializadores estáticos que consomem todo o espaço de pilha.

Ver Estouro de Pilha pergunta Como aumentar o Java tamanho da pilha?.

A técnica abaixo ajudou-me muitas vezes:

System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());

onde o TheNoDefFoundClass é a classe que pode ser "perdida" devido à preferência por uma versão mais antiga da mesma biblioteca utilizada pelo seu programa.Esta é a mais freqüentemente acontece com os casos, quando o software de cliente está sendo implantado em uma dominante recipiente, armado com a sua própria classloaders e toneladas de antigas versões mais populares de libs.

Eu fixo meu problema desativando o preDexLibraries para todos os módulos:

dexOptions {
        preDexLibraries false
        ...

NoClassDefFoundError também pode ocorrer quando um estática inicializador tenta carregar um recurso de pacote que não está disponível em tempo de execução, por exemplo, um arquivo de propriedades que a classe afetado tenta carregar a partir do META-INF diretório, mas não existe.Se você não pegar NoClassDefFoundError, às vezes você não será capaz de ver o conteúdo completo rastreamento de pilha;para superar isso, você pode utilizar temporariamente um catch cláusula Throwable:

try {
    // Statement(s) that cause the affected class to be loaded
} catch (Throwable t) {
    Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}

Se alguém vem aqui por causa de java.lang.NoClassDefFoundError: org/apache/log4j/Logger erro, no meu caso, foi produzido porque eu usei o log4j 2 (mas eu não adicionar todos os arquivos que vêm com ele), e alguns dependência biblioteca usada log4j 1.A solução foi adicionar o Log4j 1.x ponte:o frasco log4j-1.2-api-<version>.jar que vem com o log4j 2.Mais informações no log4j 2 migração.

Dois diferentes checkout cópias do mesmo projeto

No meu caso, o problema foi o Eclipse da incapacidade de diferenciar entre duas cópias diferentes de um mesmo projecto.Eu tenho um bloqueado no tronco (SVN controle de versão) e com o outro trabalhando em um ramo ao mesmo tempo.Eu tentei uma mudança na cópia de trabalho como um caso de teste com JUnit, que incluiu a extração de uma particular classe interna para ser uma classe pública por sua própria e enquanto ele estava trabalhando, eu abrir a outra cópia do projeto para olhar ao redor em alguma outra parte do código que as mudanças necessárias.Em algum ponto, a NoClassDefFoundError apareceu reclamando que a classe interna não estava lá;clicando duas vezes no rastreamento de pilha me trouxe para o arquivo de origem no projeto errado copiar.

Fechando o tronco cópia do projeto e execução do caso de teste novamente, me livrar do problema.

Este erro pode ser causado por não verificada A versão Java os requisitos.

No meu caso, eu era capaz de resolver este erro, enquanto a construção de um projeto open-source, por comutação de Java 9 para o Java 8 usando SDKMAN!.

sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu

Em seguida, fazer uma instalação limpa, como descrito abaixo.


Quando utilizar Maven como sua ferramenta de compilação, às vezes é útil-e, geralmente, gratificante, para fazer um limpa 'instalar' construir com o teste de deficiência.

mvn clean install -DskipTests

Agora que tudo foi construído e instalado, você pode ir em frente e executar os testes.

mvn test

Eu tenho NoClassDefFound erros quando eu não exportar uma classe sobre a "Ordem e Exportação na guia" Java Build Path do meu projeto.Certifique-se de colocar uma marca de verificação na "Ordem e Exportação" guia de quaisquer dependências você adicionar ao projecto de construção do caminho.Ver Eclipse aviso:XXXXXXXXXXX.jar não serão exportados ou publicado.Tempo de execução ClassNotFoundExceptions pode resultar.

Java foi possível encontrar a classe em tempo de execução.Classe A foi no projeto maven ArtClient a partir de um espaço de trabalho diferentes.Então eu importados ArtClient para o meu projeto Eclipse.Dois dos meus projetos foi usando ArtClient como dependência.Eu mudei de referência de biblioteca de referência de projeto para esses queridos (Build Path -> Configure Build Path).

E o problema foi embora.

Eu tive o mesmo problema, e eu estava estoque por muitas horas.

Eu encontrei a solução.No meu caso, não foi o método estático definido, devido a isso.A JVM não pode criar a outro objeto dessa classe.

Por exemplo,

private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");

Eu tenho essa mensagem após a remoção de dois arquivos do diretório SRC biblioteca, e quando eu trouxe de volta continuei a ver esta mensagem de erro.

A minha solução foi:Reinicie O Eclipse.Desde então, eu não vi essa mensagem novamente :-)

Certifique-se de que este corresponde no module:app e module:lib:

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }

    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top