Java: NoClassDefFoundError e ClassNotFoundException

Palavras-chave: Java, classes não encontradas, classpath

Os erros NoClassDefFoundError e ClassNotFoundException acontecem com frequência em aplicações Java e é importante entendê-los com clareza, a fim de diagnosticar problemas mais rapidamente.

Ambos os erros significam essencialmente a mesma coisa: uma classe não foi encontrada. A diferença é a maneira de que esta classe estava sendo procurada.

No caso do NoClassDefFoundError, a JVM estava tentando carregar uma classe para invocar um método ou criar uma instância e não a encontrou. Isso acontece tipicamente quando a JVM encontra uma referência a uma classe que ainda não foi carregada.

Para provocar isso como exemplo, crie um programa com duas classes, chamadas Main e Pessoa:

public class Main {
  public static void main(String[] args) {
    new Pessoa();
  }
}
class Pessoa {}

Compile este código manualmente (javac *.java) e execute-o. O programa deve rodar sem nenhum problema. Agora, remova o arquivo gerado chamado Pessoa.class e re-execute o programa. Isso gerará uma saída parecida com esta:

# java Main
Exception in thread "main" java.lang.NoClassDefFoundError: Pessoa
        at Main.main(Main.java:3)

Quando você compilou o código, a classe Pessoa estava também sendo compilada (ela poderia estar no classpath) e instrução ‘new’ fez uma referência direta a ela. No momento de executar o código, a classe Pessoa não estava mais disponível. Isso é um erro inesperado, portanto NoClassDefFoundError é um java.lang.Error.

Já a ClassNotFoundException é uma java.lang.Exception, um tipo de erro mais “suave”. Esta exceção acontece quando alguma parte do código (seu ou de alguma classe que você utiliza) está carregando explicitamente uma classe, através de métodos como Class.forName(), ClassLoader.findSystemClass() ou ClassLoader.loadClass(). Neste caso, o código não precisa ter sido compilado junto a classe referenciada.

Considere o exemplo a seguir:

public class Main {
  public static void main(String[] args) throws Exception {
    Object o = Class.forName("pacote.NaoExiste").newInstance();
  }
}

Isso produzirá uma saída parecida com:

# java Main
Exception in thread "main" java.lang.ClassNotFoundException: pacote.NaoExiste
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)

No momento da compilação, a classe não estava presente, mas o código foi compilado sem problemas. Na execução, porém, a ausência da classe fez o carregamento explícito falhar.

This entry was posted in Java. Bookmark the permalink.

3 Responses to Java: NoClassDefFoundError e ClassNotFoundException

  1. Wagner Francisco Mezaroba says:

    Ótima explicação, exemplos bem claros!

    Procurei por isso agora, estou com esse problema com o iReports. Deve ser algum problema na instalação dele.

    Valeu!

  2. aline says:

    Parabéns, está tudo bem claro.Gostei muito…

  3. Dyego says:

    Muito bom. Objetivo e claro.

Comments are closed.