Galera, existe algum meio de se adicionar metodos a uma classe existente via codigo?? Utilizando o hibernate eu vi que ele faz isso. Por exemplo:
Eu fiz um bean e mapeiei ele no hibernate. Existe uma opcao chamada Lazy que faz com que as referencias só sejam importadas quando acessar ela. Ai chamando o getClass().getMethods da minha classe bean, eu vi que o hibernate cria um metodo la que nao existe no meu bean original. Como isso é possivel? Ele faz isso via codigo provavelmente, já que eu criei meu bean, defini os metodos e atributos. Será que seria serializando e adicionando via texto ou algo do tipo? Em fim, como eu poderia fazer isso via codigo??? Vlw galera
Talvez seria possível utilizando POA - programação orientada a aspectos.
O hibernate cria proxies em tempo de execução, usando bibliotecas que geram bytecode como cglib e asm. Cara, se você precisa tanto disso, use linguagens mais dinâmicas como Ruby ou Python.
Até!
uma alternativa no mundo java seria groovy, utilizando closures
[quote]gpviani
Post 13/04/2008 22:12:11 Assunto: Re:Adiconando metodos programaticamente…
Talvez seria possível utilizando POA - programação orientada a aspectos.
[/quote]
O que seria POA?
[quote]maquiavelbona
Post 13/04/2008 22:31:41 Assunto: Re:Adiconando metodos programaticamente…
O hibernate cria proxies em tempo de execução, usando bibliotecas que geram bytecode como cglib e asm. Cara, se você precisa tanto disso, use linguagens mais dinâmicas como Ruby ou Python.
Até![/quote]
O Unico modo seria gerando essas classes via codigo em bycodes? Caraca que complicacao. Nao é que eu precise muito disso, eu tava querendo fazer algo do tipo gerar classes bean atravez de strings, tipo um json. É complicado utilizar essa cglib ou asm? Vlw
[quote]LuksS
Post 13/04/2008 23:51:34 Assunto: Re:Adiconando metodos programaticamente…
uma alternativa no mundo java seria groovy, utilizando closures[/quote]
O que seria esse closures?
[quote=mizael86]…
O que seria POA[/quote]
[quote=mizael86]…
O Unico modo seria gerando essas classes via codigo em bycodes? Caraca que complicacao. Nao é que eu precise muito disso, eu tava querendo fazer algo do tipo gerar classes bean atravez de strings, tipo um json. É complicado utilizar essa cglib ou asm? Vlw
[/quote]
Inserir métodos em classes em tempo de execução é essa complicação mesmo. Cglib e asm são complicados de trabalhar, não é coisa de um fim de semana para aprender.
[quote=mizael86]…
O que seria esse closures?
[/quote]
Até!
Eu faço mais ou menos isso com Reflection, onde tenho até um sistema de interação Javascript/Java onde Javascript chama classes e métodos em Java. No entanto as classes a serem chamadas já existem e não são geradas on the fly.
Acho que Spring também tem algo para isso também.
Mas Creio que Reflection pode ser sua resposta.
Ou se for algo com Javascript pode usar o Rhino: www.mozilla.org/rhino/
Cara, o Spring faz isso por meio de AOP.
Vc pode injetar scripts JRuby, Groovy ou BeahScriptShell em uma classe java e vice-versa, bem como classes java em outras classes java.
Dê uma olha em Spring In Action, Manning 2008 (capítulo 4).
Conselho: não reinvente a roda pra isso, use algum framework/biblioteca já pronta para tal, caso contrário vc vai se deparar com muitos problemas cabeludos e vai complicar em muito a manutenção da sua aplicação (um dos problemas com os quais vc vai se deparar de cara é o próprio classloader do java).
Woody
Não, ele não faz isso. Parece que faz isso…
Ele usa o padrão Proxy para interceptar os seus métodos e dirigir para outros.
O proxy é um outro objeto de um classe diferente. Ele tem métodos diferentes.
Sem usar reflection ou nenhum biblioteca que manipula o bytecode vc tb pode criar proxies de interfaces com
a classe Proxy do JSE.
É bem simples. Vc diz qual a interface que quer que o proxy apresente e um manipulador que intercepta todos os métodos. O codigo real é criado dinamicamente , mas os métodos não são criados dinamicamente. eles são definidos na interface.
O que o Hibernate usa é um Proxy mais sofisticado em que vc pode interceptar métodos de um classe ( não um interface). Ele cria um proxy que tem a mesma estrutura que a classe original, mas ele intercepta todos os métodos e os envia para o manipulador. O manipulador pode escolher invocar o método original na classe original ou fazer qualquer outra coisa.
Esta tecnica permite que vc execute qualquer código antes, depois ou em vez do codigo original da classe.
Existe um paradigma de programação que se baseia nesta tecnica chamado Aspect Oriented Programing : Programação Orientada a Aspectos(POA). Aspectos são esses códigos que correm antes, depois ou em vez do codigo original.
Enfim, não ha criação dinamica de métodos. Apenas ha invocação e delegação dinamica de métodos através de um mecanismo de intercepção.
Ele faz isso usando as bibliotecas ASM e CGLIB. Tem tambem a BCEL. tem outras que permitem que voce faca isso com alto nivel.
Mais importante é voce ver se realmente precisa disso! Muita magia negra para pouco trabalho é sempre complexidade desnecessaria.
Sérgio…
Com ASM e CGLIB é possível gerar um interface em tempo de execução, e se não me engano, o proxy utilizado pelo hibernate faz uso de uma interface gerada em runtime para utilzá-la no processo que você mencionou.
até
[quote=Paulo Silveira]Ele faz isso usando as bibliotecas ASM e CGLIB. Tem tambem a BCEL. tem outras que permitem que voce faca isso com alto nivel.
[/quote]
A javassist é bem alto nivel. Tão alto que é muito semelhante à classe Proxy do JSE padrão.
ASM, CGLib , BCEL e outras são muito mais complexas de usar. A diferença é como entre assembler e java.
O programador só pode passar ao nivel seguinte se souber usar magia negra desse tipo.
Caso contrário será sempre um aprendiz :twisted:
Tudo bem, mas criar uma interface é diferente de cria um método.
Mas não faz muito sentido criar uma interface do nada…
posso citar mais outro exemplo.
o jpox, framework para mapeamente objeto-relacional, implementação referencia do jdo 2.0,
faz isso em seu enhance.
[quote=sergiotaborda]O programador só pode passar ao nivel seguinte se souber usar magia negra desse tipo.
Caso contrário será sempre um aprendiz :twisted: [/quote]
Próximo nível? LOL
Somos todos aprendizes, apenas o salário é diferente …
Vc já ouvio falar na sigla KISS ?
Sim. Mas bytecode manipulation é o que permite que vc use coisas como Hibernate, JPA , Injeção , AutoWire , Webservices, e muito mais de forma simples. Para que os estupidos usem de forma simples alguem teve que fazer magia negra. :evil:
Existem os que usam e existem os que fazem. Ha sim diferentes niveis.
(Para que não sabe KISS = Keep it Simple, Stupid! )
[quote=sergiotaborda]Existem os que usam e existem os que fazem.[/quote]Sempre foi assim, IMHO isso não tem nada a ver com nível - mas sim com pró-atividade/necessidade. Conheço gente em diversos projetos no jakarta - gente que faz, como vc disse - e nem por isso eles estão em “outro nível” …
[quote=agodinhost][quote=sergiotaborda]Existem os que usam e existem os que fazem.[/quote]Sempre foi assim, IMHO isso não tem nada a ver com nível - mas sim com pró-atividade/necessidade. Conheço gente em diversos projetos no jakarta - gente que faz, como vc disse - e nem por isso eles estão em “outro nível” …
[/quote]
Acho que vc está super-valorizando a palavra nivel.
No texto original eu estava fazendo uma analogia (magia-negra + nivel = rpg ) para subit de nivel vc precisa saber magia-negra. E subir de nivel significava exatamente isso: saber usar magia-negra.
Não ha referencia à capacidade ou estupidez de ninguem.
[quote=sergiotaborda][quote=agodinhost][quote=sergiotaborda]Existem os que usam e existem os que fazem.[/quote]Sempre foi assim, IMHO isso não tem nada a ver com nível - mas sim com pró-atividade/necessidade. Conheço gente em diversos projetos no jakarta - gente que faz, como vc disse - e nem por isso eles estão em “outro nível” …
[/quote]
Acho que vc está super-valorizando a palavra nivel.
No texto original eu estava fazendo uma analogia (magia-negra + nivel = rpg ) para subit de nivel vc precisa saber magia-negra. E subir de nivel significava exatamente isso: saber usar magia-negra.
Não ha referencia à capacidade ou estupidez de ninguem.[/quote]
Para subir de nível tem que matar bastante bicho até acumular experiência suficiente.
E existem determinadas magias que requerem que o seu personagem atinja um nível mínimo para você poder usar.
Caraca, isso virou uma discursao de rpg foi kkkk.
Eu concordo que fazer “magia negra” é necessario para aprender, e aperfeiçoar-se.
Respondendo ao Paulo, eu realmente nao preciso muito disso, apenas fiquei com a curiosidade aguçada, pois é uma tecnica fascinante, e permite muita generalização de codigo.
Eu estive estudando a cglig e asm, e realmente da pra fazer isso. Tambem vi a questao do proxy, que seria interceptar metodo. Mais essa interceptação já eh uma escrita em byte code, pois ele cria uma classe que sobrescreve todos seus metodos, e entao faz essa classe extender a sua, de forma que todos os metodos que vc chamar, ele chama primeiro o da classe criada e depois chama sua, e o codigo de interceptacao é vc quem define.
Quando a nivel de programadores, eu acho que existe apenas uma diferença entre eles: os bons e os ruins. Os bons sao aqueles q gostam, que procuram e que buscam fazer as coisas por prazer. E existe os ruins, que sao os q se esforçam por obrigação, mais nunca chega a um nivel de um bom.
Acho q todos nos somos capazes de fazer qualquer coisa, basta realmente quer, se alguem aprendeu, vc pode aprender, eu posso. Nenhum programador da google ou do projeto jakarta é melhor que agente, ele apenas teve mais necessidades e buscou mais coisas, e eh isso que faz vc um bom programador. Vlw pela resposta de todos. Abraços