Pergunta

O que é a diferença entre NoClassDefFoundError e ClassNotFoundException?

O que os faz ser jogado? Como eles podem ser resolvidos?

muitas vezes eu encontro estes throwables ao modificar o código existente para incluir novos arquivos jar. Eu atingi-los em ambos os lados do cliente e do lado do servidor para uma aplicação java distribuído através webstart.

As possíveis razões que se deparam:

  1. pacotes não incluídos no build.xml para o lado do cliente de código
  2. runtime classpath faltando para os novos frascos estamos usando
  3. conflitos de versão com frasco anterior

Quando eu encontrar estes hoje eu tomo uma abordagem trilha e erro para fazer as coisas funcionarem. Preciso de mais clareza e compreensão.

Foi útil?

Solução

A diferença entre as Especificações da API Java é a seguinte.

Para ClassNotFoundException :

Lançada quando uma aplicação tenta carregar em uma classe por meio de sua corda nomear usando:

  • O método forName em Class classe.
  • O método findSystemClass em ClassLoader classe.
  • O método loadClass em ClassLoader classe.

, mas nenhuma definição para a classe com o nome especificado pôde ser encontrado.

Para NoClassDefFoundError :

Lançada se a Java Virtual Machine ou um exemplo ClassLoader tenta carregar na definição de uma classe (como parte de uma chamada de método normal ou como parte de a criação de uma nova instância usando o novo expressão) e nenhuma definição do classe poderia ser encontrado.

A procuradas definição de classe existia quando o atualmente em execução classe foi compilado, mas a definição já não pode ser encontrado.

Assim, parece que a NoClassDefFoundError ocorre quando a fonte foi compilado com sucesso, mas em tempo de execução, os arquivos class necessários não foram encontrados. Isso pode ser algo que pode acontecer na distribuição ou produção de arquivos JAR, onde não foram incluídos todos os arquivos class necessários.

Como para ClassNotFoundException, parece que ele pode decorrer de tentar fazer chamadas reflexivas para classes em tempo de execução, mas é não existe as classes o programa está tentando chamar.

A diferença entre os dois é que um é um Error e o outro é um Exception. Com NoClassDefFoundError é um Error e surge a partir das Java Virtual Machine tendo problemas para encontrar uma classe que esperava encontrar. Um programa que era esperado para o trabalho em tempo de compilação não pode ser executado por causa de arquivos class não ser encontrado, ou não é o mesmo que foi produzido ou encontradas em tempo de compilação. Este é um erro bastante crítico, como o programa não pode ser iniciado pelo JVM.

Por outro lado, o ClassNotFoundException é um Exception, por isso é um pouco esperado, e é algo que é recuperável. Usando reflexão é pode ser propenso a erros (como há algumas expectativas de que as coisas podem não saem como o esperado. Não há nenhuma verificação de tempo de compilação para ver que existem todas as classes necessárias, portanto, quaisquer problemas em encontrar as classes desejadas aparecerá em tempo de execução .

Outras dicas

A ClassNotFoundException é lançada quando a classe relatado não é encontrado pela ClassLoader. Isso normalmente significa que a classe está faltando no CLASSPATH. Também pode significar que a classe em questão está a tentar ser carregado a partir de outra classe que foi carregado num carregador de classe progenitor e, portanto, a classe do carregador de classe criança não é visível. Isso às vezes é o caso quando se trabalha em ambientes mais complexos, como um aplicativo de servidor (WebSphere é famoso por tais questões carregador de classe).

Muitas vezes as pessoas tendem a confundir java.lang.NoClassDefFoundError com java.lang.ClassNotFoundException no entanto há uma distinção importante. Por exemplo uma exceção (um erro muito desde java.lang.NoClassDefFoundError é uma subclasse de java.lang.Error) como

java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory

não significa que a classe ActiveMQConnectionFactory não está no CLASSPATH. De facto a sua muito pelo contrário. Isso significa que o ActiveMQConnectionFactory classe foi encontrado pela ClassLoader no entanto ao tentar carregar a classe, ela correu para um erro ao ler a definição de classe. Isso normalmente acontece quando a classe em questão tem blocos estáticos ou membros que utilizam uma classe que não é encontrado pela ClassLoader. Então, para encontrar o culpado, ver a fonte da classe em questão (ActiveMQConnectionFactory neste caso) e olhar para o código usando blocos estáticos ou membros estáticos. Se você não tiver acesso à fonte, em seguida, simplesmente decompile-lo usando JAD.

Ao examinar o código, digamos que você encontrar uma linha de código como abaixo, certifique-se de que o SomeClass classe em seu CLASSPATH.

private static SomeClass foo = new SomeClass();

Dica: Para descobrir qual jar uma classe pertence, você pode usar o jarFinder web site. Isso permite que você especifique um nome de classe usando wildcards e ele procura a classe em seu banco de dados de frascos. jarhoo permite que você faça a mesma coisa, mas a sua não livre para uso.

Se você gostaria de localizar o que jar uma classe pertence a em um caminho local, você pode usar um utilitário como jarscan ( http://www.inetfeedback.com/jarscan/ ). Você acabou de especificar a classe que você gostaria de localizar e o caminho do diretório raiz onde você gostaria que ele para iniciar a pesquisa para a classe em frascos e arquivos zip.

NoClassDefFoundError é um erro de ligação, basicamente. Ela ocorre quando você tenta e instanciar um objeto (estaticamente com "novo") e não é encontrado quando era durante a compilação.

ClassNotFoundException é mais geral e é uma exceção de tempo de execução quando você tentar usar uma classe que não existe. Por exemplo, você tem um parâmetro em uma função aceita uma interface e alguém passa em uma classe que implementa essa interface, mas você não tem acesso à classe. Ele também cobre caso de carregamento de classe dinâmica, como o uso loadClass() ou Class.forName().

A NoClassDefFoundError (NCDFE) acontece quando seu código é executado "nova Y ()" e pode não encontrar a classe Y.

Pode ser simplesmente que Y está ausente do seu carregador de classe como os outros comentários sugerem, mas pode ser que a classe Y não está assinado ou tem uma assinatura inválida, ou que Y é carregado por um carregador de classe diferente, não visível ao seu código, ou mesmo que Y depende de Z, que não pôde ser carregado para qualquer das razões acima.

Se isso acontecer, então a JVM vai se lembrar do resultado de carga X (NCDFE) e ele vai simplesmente jogar uma nova NCDFE cada vez que você pedir Y sem dizer-lhe porquê:

class a {
  static class b {}
  public static void main(String args[]) {
    System.out.println("First attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
    System.out.println("\nSecond attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
  }
}

Salvar como a.java algum lugar

O código simplesmente tenta instanciar um novo "b" classe duas vezes, para além disso, ele não tem quaisquer bugs, e não fazer nada.

Compilar o código com javac a.java, Em seguida, execute uma invocando java -cp . a -. Ele deve apenas imprimir duas linhas de texto, e deve correr bem, sem erros

Em seguida, exclua o arquivo "a $ b.class" (ou preenchê-lo com o lixo, ou copiar a.class sobre ele) para simular a classe ausente ou corrompido. Eis o que acontece:

First attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:5)
Caused by: java.lang.ClassNotFoundException: a$b
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 1 more

Second attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:7)

a primeira invocação resulta em uma ClassNotFoundException (jogado pelo carregador de classes quando não pode encontrar a classe), que deve ser envolto em um NoClassDefFoundError desmarcada, uma vez que o código em questão (new b()) deverá funcionar.

A segunda tentativa será, naturalmente falhar também, mas como você pode ver a exceção envolto não é mais, porque o ClassLoader parece se lembrar de carregadores de classe falhou. Você vê apenas o NCDFE com absolutamente nenhuma pista sobre o que realmente aconteceu.

Então, se você já viu um NCDFE sem causa raiz, você precisa ver se você pode acompanhar de volta para a primeira vez que a classe foi carregado para encontrar a causa do erro.

A partir http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :

ClassNotFoundException : ocorre quando a classe loader não poderia encontrar a classe necessária caminho de classe. Então, basicamente você deve verificar o seu caminho de classe e adicionar a classe no classpath.

NoClassDefFoundError : isso é mais difícil para depurar e encontrar a razão. Esta é lançada quando em tempo de compilação as classes necessárias estão presentes, mas em tempo de execução as aulas são alterados ou removidos ou inicializa estáticos da classe jogou exceções. Isso significa que a classe que está sendo carregado está presente no caminho de classe, mas uma das classes que são exigidas por esta classe são removidos ou falhou a carga pelo compilador. Portanto, você deve ver as classes que dependem desta classe.

Exemplo :

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

Agora, depois de compilar ambas as classes, se você excluir o arquivo Test1.class e executar classe de teste, ele vai jogar

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more

ClassNotFoundException:. Acionada quando um aplicativo tenta carregar em uma classe por meio de seu nome, mas nenhuma definição para a classe com o nome especificado poderia ser encontrado

NoClassDefFoundError:. Lançada se o Java Virtual Machine tenta carregar na definição de uma classe e nenhuma definição da classe poderia ser encontrado

Qual é a razão para obter cada um deles e qualquer processo de pensamento sobre como lidar com esses erros?

Eles estão intimamente relacionados. A ClassNotFoundException é lançada quando Java fui à procura de uma classe particular pelo nome e não podia carregá-lo com sucesso. A NoClassDefFoundError é lançada quando Java fui à procura de uma classe que estava ligado em algum código existente, mas não conseguiu encontrá-lo por uma razão ou outra (por exemplo, classpath errado, versão errada do Java, versão errada de uma biblioteca) e é completamente fatal, pois indica que algo deu muito errado.

Se você tem um fundo C, uma CNFE é como um fracasso para dlopen() / dlsym() e um NCDFE é um problema com o ligador; no segundo caso, os arquivos de classe em questão nunca deveria ter sido, na verdade, compilado na configuração que você está tentando usá-los.

Exemplo # 1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

Se com/example/Class1 não existe em nenhum dos caminhos de classe, então ele joga ClassNotFoundException.

Exemplo # 2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

Se com/example/Class2 existiu durante a compilação B, mas não foi encontrado durante a execução, então ele joga NoClassDefFoundError.

Ambos são executados exceções de tempo.

ClassNotFoundException é acionada quando há tentar carregar a classe referenciando-lo através de uma string. Por exemplo, o parâmetro no Class.forName () é uma String, e isso aumenta o potencial de nomes binários inválidos sendo passados ??para o carregador de classe.

O ClassNotFoundException é acionada quando um nome binário potencialmente inválido é encontrado; por exemplo, se o nome da classe tem o caráter '/', você é obrigado a obter um ClassNotFoundException. Ele também é lançada quando a classe diretamente referenciado não está disponível no classpath.

Por outro lado, NoClassDefFoundError é jogado

  • quando a representação física real da classe - o arquivo .class não estiver disponível,
  • ou a classe sido já carregado num carregador de classe diferente (normalmente um carregador de classes pai teria carregado a classe e, portanto, a classe não podem ser carregados de novo),
  • ou se uma definição de classe incompatível foi encontrado - o nome no arquivo de classe não corresponde ao nome solicitado,
  • ou (mais importante) se uma classe dependente não pode ser localizado e carregado. Neste caso, a classe diretamente referenciada pode ter sido localizado e carregado, mas a classe dependente não está disponível ou não pode ser carregado. Este é um cenário em que a classe directamente referenciado pode ser carregado através de um Class.forName ou métodos equivalentes. Isso indica uma falha na ligação.

Em suma, um NoClassDefFoundError é geralmente jogado on new () declarações ou invocações de método que a carga de uma classe anteriormente ausente (em oposição ao carregamento baseada em série de classes para ClassNotFoundException), quando o carregador de classe é incapaz de encontrar ou carregar o definição de classe (s).

Por fim, é até a implementação ClassLoader para lançar uma instância de ClassNotFoundException quando é incapaz de carregar uma classe. A maioria das implementações classloader personalizado executar esta, uma vez que estender a URLClassLoader. Normalmente classloaders não jogue explicitamente um NoClassDefFoundError em qualquer das implementações de método -. Essa exceção é geralmente jogado do JVM no compilador HotSpot, e não pelo próprio carregador de classe

Diferença entre ClassNotFoundException Vs NoClassDefFoundError

 enter descrição da imagem aqui

com o próprio nomes podemos facilmente identificar um de Exception e outro é de Error.

Exceção: Exceções ocorre durante a execução do programa. Um programador pode lidar com estes excepção pela tentativa bloco de captura. Temos dois tipos de exceções. exceção verificada que lança em tempo de compilação. Exceções de tempo de execução que são jogados em tempo de execução, estes exceção geralmente acontecem por causa da má programação.

Erro: Estes não são exceções em tudo, ele está fora do âmbito de programador. Esses erros são geralmente jogado por JVM.


enter descrição da imagem aqui fonte de imagem

Difference:

ClassNotFoundException:

  • Class loader não consegue verificar um código de classe byte mencionamos em fase de ligação de carregamento da classe subsistema chegarmos ClassNotFoundException.
  • ClassNotFoundException é uma exceção verificada derivada diretamente da classe java.lang.Exception e você precisa fornecer manipulação explícita para ele
  • ClassNotFoundException surge quando há um carregamento explícita da classe está envolvido, fornecendo nome da classe em tempo de execução usando ClassLoader.loadClass (), Class.forName () e ClassLoader.findSystemClass ().

NoClassDefFoundError:

  • Class loader não consegue resolvendo referências de uma classe em fase de ligação de carregamento da classe subsistema chegarmos NoClassDefFoundError.
  • NoClassDefFoundError é um erro derivada da classe LinkageError, que é usado para indicar casos de erro, onde uma classe tem uma dependência em alguma outra classe e essa classe tem incompatibly alterado após a compilação.
  • NoClassDefFoundError é um resultado de carregamento implícito de classe por causa de uma chamada de método de classe ou qualquer acesso variável.

Semelhanças:

  • Ambos NoClassDefFoundError e ClassNotFoundException estão relacionados à indisponibilidade de uma classe em tempo de execução.
  • Ambos ClassNotFoundException e NoClassDefFoundError estão relacionados com classpath Java.

Dadas as ações loader sussystem Classe:

http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

Este é um artigo que me ajudou muito a entender a diferença: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

Se ocorrer um erro durante o carregamento de classe, em seguida, uma instância de uma subclasse de LinkageError deve ser jogado em um ponto no programa que (Directamente ou indirectamente) usa a classe ou de interface a ser carregado.

Se o Java Virtual Machine sempre tenta carregar uma classe C durante verificação (§5.4.1) ou resolução (§5.4.3) (mas não inicialização (§5.5)), e o carregador de classe que é utilizada para iniciar a carga do C lança uma instância de ClassNotFoundException , então o Java Virtual Máquina deve lançar uma instância de NoClassDefFoundError cuja causa é a instância de ClassNotFoundException .

Assim, um ClassNotFoundException é uma causa raiz de NoClassDefFoundError .
E um NoClassDefFoundError é um caso especial de erro de tipo de carga, que ocorre em Ligar etapa.

Adicionar uma razão possível na prática:

  • ClassNotFoundException: como cletus disse, você usar a interface, enquanto classe herdada da interface não está no classpath. Por exemplo, Serviço Padrão Provider (ou Service Locator ) tentar localizar alguns não -existente classe
  • NoClassDefFoundError: determinada classe é encontrado, enquanto a dependência de determinada classe não for encontrada

Na prática, Erro pode ser jogado silenciosamente , por exemplo, você enviar uma tarefa temporizador e na tarefa temporizador ele lança Erro , enquanto que na maioria dos casos, o programa apenas capturas Exceção . Em seguida, o Temporizador loop principal é encerrado sem qualquer informação. Um erro semelhante ao NoClassDefFoundError é ExceptionInInitializerError , quando o seu estática initializer ou o inicializador para uma variável estática lança uma exceção.

ClassNotFoundException é uma exceção verificada que ocorre quando dizemos a JVM para carregar uma classe por seu nome string usando Class.forName () ou ClassLoader.findSystemClass () ou ClassLoader.loadClass () métodos e mencionou classe não é encontrada no classpath.

Na maioria das vezes, essa exceção ocorre quando você tenta executar um aplicativo sem atualizar o classpath com arquivos JAR necessários. Por exemplo, você pode ter visto essa exceção ao fazer o código JDBC para se conectar ao seu banco de dados i.e.MySQL mas seu classpath não tem JAR para ele.

NoClassDefFoundError erro ocorre quando JVM tenta carregar uma classe particular que é a parte de sua execução de código (como parte de uma chamada de método normal ou como parte da criação de uma instância usando a nova palavra-chave) e essa classe não está presente no seu classpath, mas estava presente em tempo de compilação porque, a fim de executar o seu programa que você precisa para compilá-lo e se você está tentando usar uma classe que não está presente compilador irá aumentar erro de compilação.

Abaixo está a descrição breve

enter descrição da imagem aqui

Você pode ler Tudo Sobre ClassNotFoundException Vs NoClassDefFoundError para mais detalhes.

Eu me lembrar o seguinte novo e de novo quando eu precisar atualizar

ClassNotFoundException

Class Hierarchy

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

Durante a depuração

  1. JAR necessários, classe está faltando no classpath.
  2. Verifique se todos os frascos necessários estão no classpath de JVM.

NoClassDefFoundError

Class Hierarchy

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

Durante a depuração

  1. O problema com o carregamento de uma classe dinamicamente, que foi compilado corretamente
  2. Problema com blocos estáticos, construtores, init () métodos de classe dependente e o erro real é envolto por camadas múltiplas [especialmente quando você usa Spring, Hibernate a exceção real é envolto e você obterá NoClassDefError]
  3. Quando você enfrentar "ClassNotFoundException" sob um bloco estático da classe dependente
  4. Problema com versões de classe. Isso acontece quando você tem duas versões v1, v2 da mesma classe sob diferentes jar / pacotes, que foi compilado com sucesso usando v1 e v2 é carregado no tempo de execução que não tem os métodos relevantes / vars e você verá esta exceção. [I uma vez resolvido esse problema removendo o duplicado da log4j classe relacionada sob vários frascos que apareceu no classpath]

ClassNotFoundException e NoClassDefFoundError ocorrer quando uma classe particular não é encontrado em runtime.However, eles ocorrem em diferentes cenários.

ClassNotFoundException é uma exceção que ocorre quando você tenta carregar uma classe em tempo de execução usando Class.forName () ou loadClass () métodos e classes mencionadas não são encontradas no classpath.

    public class MainClass
    {
        public static void main(String[] args)
        {
            try
            {
                Class.forName("oracle.jdbc.driver.OracleDriver");
            }catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
    }



    java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pack1.MainClass.main(MainClass.java:17)

NoClassDefFoundError é um erro que ocorre quando uma classe particular está presente em tempo de compilação, mas estava faltando em tempo de execução.

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

Quando você compilar o programa acima, dois arquivos .class será gerada. Um deles é A.class e outra é B.class. Se você remover o arquivo A.class e execute o arquivo B.class, Java Runtime Sistema vai jogar NoClassDefFoundError como abaixo:

    Exception in thread "main" java.lang.NoClassDefFoundError: A
    at MainClass.main(MainClass.java:10)
    Caused by: java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top