Alterando o classloader

8 respostas
Guilherme_Silveira

estou usando o janino para compilar algumas classes em tempo de execucao e ele me devolve um classloader com o qual eu tenho acesso a essas classes compiladas.

para alterar o classloader do sistema em tempo de execucao so achei a alternativa que usa reflection para alterar a variavel estatica scl da classe ClassLoader (entenda como gambiarra total)

na verdade quero alterar o classloader para uma parte especifica do programa, mas o meu codigo deve funcionar como algo plugavel: nao posso alterar a linha de comando nem nada. tem que ser so de colocar o jar no classpath ele faz isso tudo sozinho

no momento estou notificando os outros componentes sobre classloader novo para que utilizem ele em suas reflections

8 Respostas

_fs

Recomendo o livro Java Reflection in Action.

louds

Guilherme explica melhor o teu problema, não ficou claro.

Eu entendi é que você precisa que os seus componentes saibam da existencia das classes geradas, correto? Class.forName funcionar, por exemplo.

Se for isso a solução mais facil é você deixar a parte de geração de classes toda no classloader normal da aplicação e o resto carregar atraves do classloader do janino. Pra isso você vai precisar de um método ponte que muda a execução do classloader da aplicação para o classloader do janino que só pode ser feito usando reflection.

Isso que eu falei é factivel e facil de fazer em J2SE, já com J2EE fica um pouco mais chato.

Guilherme_Silveira

Entao louds, eu acho que fiz o que voce falou.

Eu acessei o field private static chamado scl do ClassLoader e alterei para o do janino e com composicao fiz acessar os outros. Mas isso eh feio pra burro, nojento, mal educado etc e tal nao acha… acessando um private static…

O Reflection in Action fala disso Lipe (ponto de interrogacao)
Nao gosto da serie in Action por causa do struts e do hibernate, o reflection eh bom (PI)

ps: teclado ruim

saoj

Fala Guilherme,

Esse era o meu problema original, mas como o Tomcat faz isso pra mim eu ignorei.

Essa sua solução de alterar o classloader por reflection funciona para classes que já tinham sido carregadas ??? Por exemplo vc carregou uma class A e depois alterou o código dela e recompilou ela. O problema é que o classloader já carregou essa classe e já guardou isso num cache, ou seja, vai ignorar a mudança.

Vc teve esse problema?

Guilherme_Silveira

nem cheguei a pensar nisso. vi que era muita gambiarra logo de cara e tentei outros caminhos mais polidos

saoj

O problema é que os classloaders usam um classloader (encadeado) embaixo que cacheia tudo. A única solução que eu vi na Net é vc usar um classloader que não delega pra baixo, ou seja, (acho) que dá um defineClass ele mesmo. Depois vc joga esse classloader fora e usa outro. Aí a classe é carregada novamente. (ela e todo o resto que depende dela :-()

Não sei se tem solução bonita pra isso não… Eu achei que o Tomcat fazia isso, mas pelo que to vendo ele força um restarte de tudo e não apenas o reload de uma classe… :frowning:

Guilherme_Silveira

a estrutura de delegar do classloader eu vi, claro. mas tentei resolver a situacao dcom dois classloaders diferentes ao mesmo tempo ai parece que deu, mas como disse ficou muito feio.

o tomcat precisa dar um reload em toda a aplicacao (eh isso?) pq se ele deixa algo para tras nesse reload de classes pode ficar tudo incompativel. sem contar que ele teria que manter para cada classe qual foi o ultimo horario de reload, mto chato e nao faz mto sentido para uma aplicacao web.

se nao me engano o reload nem eh padrao do j2ee, alguem confirma? (pelo menos nao li na especificacao)

_fs

Eu achei bastante bom, já que manjava absolutamente nada de classloading em Java. No capítulo pertinente o autor constói um classloader :smiley:

Ele aborda outros temas além da API de Reflection, e bem aplicado. Achei ótimo.

Criado 30 de julho de 2005
Ultima resposta 2 de ago. de 2005
Respostas 8
Participantes 4