Mirror 1.6 e outros projetos

27 respostas
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/

Além dele, foi lançado a versão 0.5 do I18n, uma forma de usar EL para fazer internacionalização de páginas Jsp. http://projetos.vidageek.net/i18n/project/release-notes/.

Outros dois projetos também foram lançados. O Crawler é uma simples spider feita em java e é usado por sites como o http://www.procurandocursos.com e o http://indiqueai.com.br/. Mais informações em http://projetos.vidageek.net/crawler/crawler/.

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 :slight_smile:

27 Respostas

Andre_Fonseca

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/

Além dele, foi lançado a versão 0.5 do I18n, uma forma de usar EL para fazer internacionalização de páginas Jsp. http://projetos.vidageek.net/i18n/project/release-notes/.

Outros dois projetos também foram lançados. O Crawler é uma simples spider feita em java e é usado por sites como o http://www.procurandocursos.com e o http://indiqueai.com.br/. Mais informações em http://projetos.vidageek.net/crawler/crawler/.

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 :)

Parabens pelos projetos :wink:

zoren

Opa, Parabéns

Já brinquei com o Mirror algumas vezes, achei muito bom.

Felagund

zoren:
Opa, Parabéns

Já brinquei com o Mirror algumas vezes, achei muito bom.

Eu uso o mirror em produção :slight_smile:

nofan

Realmente fantasticos os projetos e ótimas atualizações, parabens!

zoren

Onde eu descubro como eu uso o

Não achei no site.

jonasabreu

http://projetos.vidageek.net/mirror-pt/proxy/

Vou ver se coloco em um lugar mais proeminente.

zoren

jonasabreu:
http://projetos.vidageek.net/mirror-pt/proxy/

Vou ver se coloco em um lugar mais proeminente.

Valeu,

Caramba, não vi mesmo, o link estava no fim do menu.

zoren

Tem algum segredo para o Proxy funcionar?

É estilo o Proxy do Java?

Tentei aqui mas deu erro

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)

Fiquei curioso para ver isso funcionando.

von.juliano
Segue um exemplo:
Object proxy = new Mirror().proxify(OneClassFixture.class, OneInterfaceFixture.class, OtherInterfaceFixture.class).interceptingWith(new MethodInterceptor() {

	public boolean accepts(final Method method) {
		return true;
	}

	public Object intercepts(final Object target, final Method method, final Object... parameters) {
		return "foo";
	}
});

System.out.println(((OneInterfaceFixture) proxy).interfaceMethod());
System.out.println(((OtherInterfaceFixture) proxy).otherInterfaceMethod());
System.out.println(((OneClassFixture) proxy).classMethod()); // OneClassFixture.classMethod() por si só retorna "test"
Blz? Flw! :thumbup:
zoren

Vlw pelo código.

Mas tenho o mesmo erro :?

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
von.juliano

Posta seu código, incluindo as classes que você está tentando proxiar.

zoren

Eu tentei com aquele seu código.

public class Main {
    public static void main(String[] args) {
        Object proxy = new Mirror().proxify(OneClassFixture.class, OneInterfaceFixture.class, OtherInterfaceFixture.class).interceptingWith(new MethodInterceptor() {
            public boolean accepts(final Method method) {
                return true;
            }
            public Object intercepts(final Object target, final Method method, final Object... parameters) {
                return "foo";
            }
        });
        System.out.println(((OneInterfaceFixture) proxy).interfaceMethod());
        System.out.println(((OtherInterfaceFixture) proxy).otherInterfaceMethod());
        System.out.println(((OneClassFixture) proxy).classMethod()); // OneClassFixture.classMethod() por si só retorna "test"
    }
}

class OneClassFixture implements OneInterfaceFixture, OtherInterfaceFixture {
    public String classMethod() {
        return "test";
    }
    @Override
    public String interfaceMethod() {
        return classMethod();
    }
    @Override
    public String otherInterfaceMethod() {
        return classMethod();
    }
}
interface OneInterfaceFixture {
    public String interfaceMethod();
}
interface OtherInterfaceFixture {
    public String otherInterfaceMethod();
}
von.juliano

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.

Blz? Flw! :thumbup:

zoren

Cara, não entendi ainda.

Estou com um problema nas minhas ideias.

Poderia colocar aquele seu código com todas as suas classes?

Eu fiz um teste sem implementar as interfaces na classe e deu o mesmo erro.

von.juliano

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:
public class UmaClasse {
	public String metodoDaClasse() {
		return "ok";
	}
}

public interface UmaInterface {
	String metodoDaInterface();
}
Vou proxiar essa classe e a interface, quero que ambos os métodos retornem "proxiado!":
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!";
	}
});
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!".

Blz? Flw! :thumbup:

zoren

No meu esse seu código continua dando o mesmo erro. :cry:

Deixa prá lá, depois eu dou um jeito nisso.

No início, eu tentei usar igual o Proxy do Java, mas também não deu em nada.

Vlw pela ajuda.

jonasabreu

Olá zoren,

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.

Valeu pelo aviso!

Raphael_Lacerda

Iae Jonas tudo bom?

Cara, parabéns!
To usando a versão 1.5 do mirror lá no BB fazendo bastante propaganda dele!

Deixa eu te fazer uma pergunta…

Atualmente, a classe GetterHandler tem os métodos para acessar os Fields do objeto.
Tem algum jeito para acessar os Methods do objeto?

G

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?

jonasabreu

@Raphael Lacerda

Não entendi direito a parte de acessar os métodos. Refletir ou invocar?

Para refletir:

Method method = new Mirror().on(seuObjeto.getClass()).reflect().method("methodName").withoutArgs();

Para invocar:

new Mirror().on(seuObjeto).invoke().method("methodName").withoutArgs();

Você encontra mais informações em http://projetos.vidageek.net/mirror-pt/method/

jonasabreu

@garcia-jj

O tamanho me incomoda também. Mas ainda acho melhor do que o possível clash de versões com hibernate por aí…

Sobre proxys, isso é algo que pensei durante muito tempo. Realmente, suporte a proxys fica em lugar meio cinza entre reflection e o resto do mundo (mesmo estando no pacote j.l.r). O meu principal ponto para adicionar o suporte a proxy é que (como comentou uma vez um amigo meu, o Rafael Ferreira), o objetivo do Mirror é se tornar uma caixinha de Magia Negra fácil de usar para o meta-modelo de objetos do Java. Criar proxys deveria ser algo bem simples em qualquer linguagem, mas em Java não é bem assim. Pensando em tudo isso resolvi começar a atacar essa “zona cinza” também.

Mas realmente é algo que fica um pouco fora dos objetivos iniciais (substituir o ReflectionUtils) mesmo que me ajude no dia-a-dia.

G

Jonas, muito bom =).

Posso sugerir para quando sair uma nova versão de derrepente ter um mirror.jar e um mirror-proxy.jar? Digamos que deixar apenas o core do mirror de um lado, e plugins/extras de outro. Enfim, uma sugestão apenas.

Abraços

jonasabreu

@garcia-jj

Essa é uma idéia que tenho (inclusive queria ter aplicado nessa versão, mas preferi ter feedback mais rápido do que segurar ainda mais a versão).

Até!

Adelar

Legal. :smiley: Não conhecia este projeto. Vou dar uma olhada logo que puder. Parece interessante.

[]'s

Diabo_Loiro

show de bola.

jonasabreu

@zoren

Você pode testar a versão que acabei de lançar (1.6.1)? Os testes que eu fiz para reproduzir o seu problema passam agora. A diferença é que agora é necessário adiconar o cglib ao seu classpath para utilizar a parte de proxys. As instruções estão em [url]http://projetos.vidageek.net/mirror-pt/proxy/[url]

@garcia-jj

Acabei movendo a dependencia para fora do Mirror mesmo. O Jar ainda está um pouco maior (137Kb) que o da versão 1.5.1 (72Kb) porque mantive o objenesis.

G

jonasabreu:
@garcia-jj

Acabei movendo a dependencia para fora do Mirror mesmo. O Jar ainda está um pouco maior (137Kb) que o da versão 1.5.1 (72Kb) porque mantive o objenesis.

:thumbup:

Criado 3 de março de 2011
Ultima resposta 19 de mar. de 2011
Respostas 27
Participantes 10