Semana passada foi lançada a versão d Mirror 1.6. Para quem não conhece, o Mirror é uma DSL para lidar com Reflection. Essa versão trás algumas melhorias, como suporte a proxys. Mais informações em http://projetos.vidageek.net/mirror-pt/projeto/release-notes/
O último projeto é o Scraper, que é uma forma mais simples de se extrair dados de documentos html (nada de XPath, DOM Traversal, etc). Mais informações em http://projetos.vidageek.net/scraper/scraper
Todo feedback (até mesmo um “Isso não serve para nada” ou um “Não reinvente a roda”) é muito bem vindo
[quote=jonasabreu]Semana passada foi lançada a versão d Mirror 1.6. Para quem não conhece, o Mirror é uma DSL para lidar com Reflection. Essa versão trás algumas melhorias, como suporte a proxys. Mais informações em http://projetos.vidageek.net/mirror-pt/projeto/release-notes/
O último projeto é o Scraper, que é uma forma mais simples de se extrair dados de documentos html (nada de XPath, DOM Traversal, etc). Mais informações em http://projetos.vidageek.net/scraper/scraper
Todo feedback (até mesmo um “Isso não serve para nada” ou um “Não reinvente a roda”) é muito bem vindo :)[/quote]
Caused by: java.lang.ClassFormatError: Duplicate method name&signature in class file App$UmaClasse$$EnhancerByCGLIB$$4d7bcdbf
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
Exception in thread "main" net.vidageek.mirror.thirdparty.net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at net.vidageek.mirror.thirdparty.net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at net.vidageek.mirror.thirdparty.net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.vidageek.mirror.thirdparty.net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at net.vidageek.mirror.thirdparty.net.sf.cglib.proxy.Enhancer.create(Enhancer.java:679)
at net.vidageek.mirror.proxy.cglib.CGLibProxyReflectionProvider.createProxy(CGLibProxyReflectionProvider.java:28)
at net.vidageek.mirror.DefaultProxyHandler.interceptingWith(DefaultProxyHandler.java:57)
at javaapplication24.Main.main(Main.java:21)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at net.vidageek.mirror.thirdparty.net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at net.vidageek.mirror.thirdparty.net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 6 more
Caused by: java.lang.ClassFormatError: Duplicate method name&signature in class file $javaapplication24/OneClassFixture$$EnhancerByCGLIB$$8613941f
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
... 12 more
Java Result: 1
Isso é um erro da sua implementação. Se a classe implementa a interface, e você tentar proxiar a classe e a interface, vai ocorrer uma exceção indicando que há métodos duplicados, da mesma forma como você não pode ter dois métodos com a mesma assinatura em uma classe.
O proxy gerado vai ter todos os métodos do objeto proxiado + todos os das demais interfaces, então se a sua OneClassFixture implementar as interfaces, os métodos já existirão no objeto, causando essa exceção.
A idéia do proxy é que ele é um objeto que finge ser outro (via polimorfismo). Em Java, tem duas formas de obter polimorfismo: Implementar uma interface ou extender uma Classe. O proxy tem que ser polimórfico com relação a tudo que for passado no proxyfy, e como só da para herdar de uma classe (mas você pode implementar inúmeras interfaces), somente uma classe (concreta ou abstrata) pode ser passada, pois é o máximo que se consegue fazer um proxy.
Agora o exemplo:
[code]public class UmaClasse {
public String metodoDaClasse() {
return “ok”;
}
}
public interface UmaInterface {
String metodoDaInterface();
}[/code]
Vou proxiar essa classe e a interface, quero que ambos os métodos retornem “proxiado!”:
[code]Object proxy = new Mirror().proxify(UmaClasse.class, UmaInterface.class).interceptingWith(new MethodInterceptor() {
public boolean accepts(final Method method) {
return true; // isso indica que quaquer método será proxiado, no caso de métodos com o mesmo retorno e numero de parâmetros, vai funcionar sem problemas
}
public Object intercepts(final Object target, final Method method, final Object... parameters) {
return "proxiado!";
}
});[/code]Agora, se você fizer o cast o proxy gerado tanto para UmaClasse e chamar metodoDaClasse() como para UmaInterface e chamar metodoDaInterface(), ele vai retornar “proxiado!”.
acabei de conseguir reproduzir o erro na minha máquina. Parece que aconteceu algum problema depois da montagem do jar (para evitar conflito de dependências optamos por inserir as classes do cglib dentro do jar e modificar os pacotes.)
Estou sem tempo agora mas no fim de semana olho isso e assim que corrigido lanço um versão corrigindo o problema.
Uma pena que assim um jar que antes era 72K atualmente tem + de 500K.
Agora pergunto: mirror é uma espécie de facilitade para reflection, inclusive o nome é bem intuitivo, sendo assim faz sentido o mirror criar proxies? Não seria uma responsabilidade além do core do mirror?