Preciso usar Reflection para um objetivo específico: incluir algoritmos (feitos por alunos) dinamicamente em um editor de grafos. Li vários exemplos e alguns textos sobre reflection, mas todos usavam as classes da API padrão Java.
Aí fica fácil usar reflection, basta usar o nome da classe precedido do pacote para acessar a classe, certo?
Pois é, mas eu preciso que o usuário use um FileChooser, por exemplo, pra escolher um .class no sistema de arquivos para usar reflection nessa classe…como eu vou fazer então pra acessar essa classe no pacote Reflection??
Vai carregar as classes dos alunos uma por uma para ver se funciona o exercício proposto? Já pensou em usar URLClassLoader para carregar cada classe? Não precisaria de um FileChooser para ler a classe, bastaria saber o nome e localização.
Se quiser complicar um pouco use Tree para localizar a classe. Mas se fosse eu ia pelo caminho mais simples.
A idéia não é de correção…é um editor que os alunos usarão para implementar algoritmos e integrá-los para que eles possam aprender a programação intrínseca a grafos sem a necessidade de fazer um editor (já que este será disponibilizado).
Aí existe mesmo a necessidade do FileChooser para que cada aluno possa incluir os seus algoritmos, sabe? Mas a idéia do URLClassLoader é boa, vou dar uma olhada na documentação dessa classe. Obrigado!!
OK, usei o URLClassLoader…o problema é que não está funcionando!
Usando o JFileChooser pra escolher o arquivo, eu obtenho o path completo do .class desejado, mas, na hora de criar a URL pro URLClassLoader, eu obtenho um MalformedURLException…
O path no teste que estou fazendo (valor da variável url) é:
“C:\Documents and Settings\eduardo\My Documents\PUC\Projeto\ge_prototipo1_0411_2230\graph_editor\graph_editor\algorithm”
e file_name vale “DepthSearch.class”…
Como havia dito, a exceção obtida é a MalformedURLException
Até acho que sei onde está errando. Mas estou sem tempo para analisar criteriosamente seu código e posso estar enganado. Melhor lhe enviar um exemplo do Stuart Halloway, ver link: http://java.sun.com/developer/TechTips//2000/tt1027.html
import java.net.*;
public class Loader {
public static void main(String [] args)
throws Exception
{
URL[] urlsToLoadFrom = new URL[]{new URL("file:subdir/")};
URLClassLoader loader1 = new URLClassLoader(urlsToLoadFrom);
URLClassLoader loader2 = new URLClassLoader(urlsToLoadFrom);
Class cls1 = Class.forName("Loadee", true, loader1);
Class cls2 = Class.forName("Loadee", true, loader2);
System.out.println("(cls1 == cls2) is " + ((cls1 == cls2) ? "true" : "false"));
}
}
//place Loadee in a subdir named 'subdir'
public class Loadee {
static {
System.out.println("Loadee class
loaded");
}
}
Compare com seu código e tente descobrir o erro. Caso não consiga sugiro dar uma estudada no Capítulo 2 do livro Component Development for the Java Platform do Stuart Halloway. Lá é uma de minhas fontes sobre ClassLoader, Reflection, Serialization, etc. Pode ir fundo que o livro é free. Faça o download dele a partir de: http://www.relevancellc.com/halloway/compsvcs/default.html
PS: Estou editando minha mensagem só para chamar a atenção sobre um erro comum no uso do ClassLoader:
tentar carregar uma classe em local encontrado pelo mecanismo implicito de carga, isto é, pelo classpath. Se a JVM já encontrou uma classe em um determinado caminho, todas as classes do mesmo caminho são carregadas pelo mesmo ClassLoader. As classes que você quer carregar pelo URLClassLoader NÃO podem ser achadas pelo classpath, faça como no exemplo e as ponha em um subdiretório. Veja livro do Halloway.
No seu caso acho que o erro parece facil de achar, compare com os exemplos.
Bom…tentei primeiro olhando o exemplo do Luca…o que faltava era o “file:” antes da URL, isso resolveu a MalformedURLException…mas aí, na chamada para loadClass, ocorreu um NoClassDefFoundError.
Agora sobre criar um ClassLoader…o que eu tenho que fazer é implementar o método para carregar os bytes da classe para que ela possa ser resolvida e, assim, usada no programa, certo?
Eu só estou achando que o ClassLoader que eu vou implementar deve fazer a mesma coisa que o URLClassLoader faz…não sei se faz muito sentido fazer um novo…vou tentar descobir esse novo erro…quem sabe? :lol:
Muito obrigado pela ajuda, pessoal…postarei notícias
(mais ajudas continuam muito bem-vindas! hehehe)
Erro bobo…o NoClassDefFoundError era porque a classe que eu estava tentando carregar tinha um pacote, e eu não coloquei esse pacote na hora de carregá-la…colocando o pacote na hora de carregar funciona direitinho!
Muito obrigado pela ajuda, pessoal! Os problemas que tive:
usar o URLClassLoader: na hora de criar a URL, colocar o “file:” antes do path se o arquivo estiver na máquina local
carregar a classe: na hora de dar o loadClass, lembrar do caminho (no meu caso, “graph_editor.algorithm.”) antes do nome da classe