Java Reflection

2 respostas
iSoron

Oi gente, estou com um problema…

Estive testando a api Java Reflection em um pequeno programinha, que carrega e descarrega classes dinamicamente. O proposito disso seria poder carregar um plugin e fazê-lo funcionar sem precisar reiniciar todo o daemon.

Pois bem, primeiro, mandei ele carregar a classe, mas, como eu ainda não havia colocado o .class no local especifico, ele disse que não conseguiu encontrar. Até aí tudo bem. Entao eu coloquei o .class lá e tentei novamente. Dessa vez, ele encontrou e tudo funcionou como esperado. Aí eu pedi que ele descarregasse, apaguei o .class e pedi que ele carregasse de novo. Pra minha surpresa, ele conseguiu carregar a classe! É como se ele tivesse uma espécie de cache, eu não sei…

E entao, como fazer ele apagar totalmente da memória a classe antiga?
Da maneira atual, ele não atualiza o plugin… :cry:

[]'s
iSoron.

2 Respostas

T

O classloader tem uma referência para a classe que carregou.

Se você usou o classloader default do sistema (é o que provavelmente você fez), a sua classe não será descarregada.

Se você criou um classloader e carregou a classe usando esse classloader, a classe somente será descarregada quando o próprio classloader for desalocado pela “garbage collection”. Você pode sugerir à JVM que faça um “garbage collection” usando System.gc(), mas não há garantia que o classloader seja realmente desalocado naquele momento; talvez isso aconteça um pouco depois. (Não adianta ficar enchendo de métodos “finalize” que isso mais atrapalha que ajuda).

É por isso que o Tomcat e outros servidores J2EE têm um esquema extremamente complicado para efetuar “hot-deploy” de aplicações.
Procure “classloader” no Google.

iSoron

Valeu pela resposta, thingol. O problema é exatamente esse.
Tentei usar o Garbage Collector, mas não é nada confiável mesmo e, na maior parte das vezes, ele mantém a classe no cache.
Pesquisando um pouco mais, achei isso:

Java classloaders do not have any standard mechanism to undeploy or unload a set of classes, nor can they load new versions of classes. In order to make updates to classes in a running virtual machine, the classloader that loaded the changed classes must be replaced with a new classloader. When a classloader is replaced, all classes that were loaded from that classloader (or any classloaders that are offspring of that classloader) must be reloaded. Any instances of these classes must be re-instantiated.

Fonte: WebLogic docs

O jeito vai ser implementar um ClassLoader que permita Hot-Deploy mesmo… :?
Um artigo sobre isso pode ser encontrado aqui:

http://www.cheblogs.com/roller/page/J2gEEk/20030726

ps.: Também vi que as applets, no console de debug, permitem fazer a limpeza no cache do ClassLoader, mas dinamicamente, não achei nada a respeito… Outra opçao seria desativar o cache pela linha de comando, mas, além de não fazer efeito nenhum, não parece uma boa ideia. :lol:

[]'s,
iSoron.

Criado 15 de fevereiro de 2005
Ultima resposta 15 de fev. de 2005
Respostas 2
Participantes 2