Mirror 1.6 e outros projetos

27 respostas
J

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

A

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:

Z

Opa, Parabéns

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

F

zoren:
Opa, Parabéns

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

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

N

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

Z

Onde eu descubro como eu uso o

Não achei no site.

J

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

Vou ver se coloco em um lugar mais proeminente.

Z

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.

Z

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.

V
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:
Z

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
V

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

Z

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();
}
V

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:

Z

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.

V

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:

Z

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.

J

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!

R

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?

J

@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/

J

@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

J

@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é!

A

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

[]'s

D

show de bola.

J

@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