Quando algum código faz uma referência para uma classe, o ClassLoader tenta carregar esta classe, caso a JVM ( Java Virtual Machine)não encontre este classe então ela lança uma exceção: ClassNotFoundException, que é uma java.lang.Exception. Existem alguns métodos que podemos utilizar para carregar uma classe:
· Class.forName(): Carrega uma classe dinamicamente, ele delega esta busca ao ClassLoader vigente. Ele carrega a classe e também causa a inicialização da classe (nas versões mais recentes do Java podemos passar um parâmetro que impede a inicialização). Este método pode gerar duas exceções: ClassNotFoundException e ExceptionInInitializerError;
· ClassLoader.findSystemClass(): Tenta carregar uma classe à partir de um ou mais caminhos, normalmente definido pelo CLASSPATH (parâmetro Java que recebe uma lista de todas as pastas em que precisa procurar classes). Este método não causa a inicialização da classe, ou seja, ele apenas carrega a classe, que será inicializada apenas quando for utilizada. Desta forma lança apenas a exceção: ClassNotFoundException;
· ClassLoader.loadClass(): Similar ao Class.forName, mas a busca pela classe pode ocorrer de qualquer nível de ClassLoader, não apenas no vigente. Ele lança apenas a exceção: ClassNotFoundException.
Utilizando os métodos acima, como as classes são carregadas dinamicamente, o código não precisa ter sido compilado junto à classe referenciada.
Geralmente há uma mensagem neste padrão:
java.lang.ClassNotFoundException: <nome da classe>
Agora será criado um código em Java para simular este erro, lançando a exceção acima:
1) Crie um arquivo chamado Principal.java, com este código:
public class Principal {
public static void main(String[] args) throws Exception {
Object objeto = Class.forName("classe.NaoExiste").newInstance();
}
}
2) Compile o programa em Java Principal.java:
javac Pricipal.java
3) Para reproduzir o problema execute a classe Principal.class:
java Principal
O ClassLoader irá tentar buscar a classe classe.NaoExiste, que não existe, então não irá encontrar a classe, lançando a exceção ClassNotFoundException. Veja erro na execução:
Exception in thread "Main Thread" java.lang.ClassNotFoundException: classe.NaoExiste
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at Principal.main(Principal.java:3)
Este é um caso complicado, pois ao compilar o código nenhum erro foi exibido. No entanto quando a classe é executada, o ClassLoader não consegue carregar a classe e a exceção é lançada.
Este erro é muito comum em casos onde o nome da classe foi digitado de forma errada (caracteres a mais ou a menos ou até mesmo diferenças de maiúsculas e minúsculas, pois o Java é sensível a estas diferenças). Pode ser que o nome foi digitado corretamente, mas a classe não foi enviada para o servidor em que o programa foi executado ou foi copiado mas a pasta onde a classe está não foi colocada no CLASSPATH.