Tempo de leitura: menos de 1 minuto
Quem (programador Java) nunca se deparou com estas exceções NoClassDefFoundError e ClassNotFoundException? Elas ocorrem com certa frequência e podem dar uma bela dor de cabeça.
Esta semana estamos homologando a nova versão do sistema no Websphere 7, e cara… que trampo hen!!
Atualmente, por algum motivo, depois que a aplicação é “deployada”, no classpath do Webphere não consta uma classe anônima do Hibernate 4.3.8 (versão que estamos usando): org.hibernate.type.descriptor.sql.DateTypeDescriptor$1. Aparentemente é algum problema na ordem do class loader, já que empacotamos o Hibernate no projeto.
Eis que aí a famigerada exceção NoClassDefFoundError é lançada, assim que um processo é executado. Sendo assim decidi escrever sobre estas exceções.
Podemos dizer que os erros significam a mesma coisa, a classe procurada não foi encontrada. No entanto, cada erro será lançado dependendo da maneira como a classe está sendo procurada.
No caso do NoClassDefFoundError, suponha que em tempo de compilação a classe está no classpath, assim nenhum erro ocorre. Já durante a execução, quando a JVM invocar um método ou uma instância de classe e a mesma não for encontrada no classpath, o erro é lançado.
Este erro pode ser provocado desta forma:
[code language=”java”]
public class TesteErro {
public static void main(String[] args) {
//referência direta para a classe ClasseQualquer
new ClasseQualquer();
}
}
class ClasseQualquer {}
[/code]
Compilando este código, o java te retornará duas class: TesteErro.class e TesteErro$ClasseQualquer.class
Quando o programa for executado, nenhum problema será notado. No entanto, se removermos a classe TesteErro$ClasseQualquer.class, e executamos o programa novamente, o erro será lançado.
A saída será algo como:
[code language=”bash”]
Exception in thread "main" java.lang.NoClassDefFoundError: ClasseQualquer
at TesteErro.main(TesteErro.java:4)
[/code]
Já a exceção ClassNotFoundException, acontece normalmente quando se usa reflexão. Se existir um código que carrega uma classe usando Class.forName() ou Class.class.getClassLoader().loadClass() e a classe não existir no classpath, o erro é lançado. Neste caso, a classe procurada, não precisa necessariamente ter sido compilada junto com a classe que à referência.
Este erro pode ser simulado desta forma:
[code language=”java”]
public class TesteErro {
public static void main(String[] args) throws Exception {
//referência indireta (qualified name) para a classe ClasseQualquer
Object o = Class.forName("esta.classe.nao.existe.ClasseQualquer").newInstance();
}
}
[/code]
A saída será algo como:
[code language=”bash”]
Exception in thread "main" java.lang.ClassNotFoundException: esta.classe.nao.existe.ClasseQualquer
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
[/code]
No exemplo a cima, a classe não precisa estar presente durante a compilação. Já na execução, a ausência da classe será percebida e a exceção é lançada.
Link permanente
Uma dica:
Aqui tem uma lista de coisas estúpidas para se checar quando ocorre ClassNotFoundException!
https://myarch.com/classnotfound/