CGLIB: Lazy sendo executado duas vezes

1 resposta
G

Criei um service locator com funcionalidades de lazy-load. Ou seja, quando você faz um get em um EJB o mesmo traz apenas um proxy, e somente quando você chamar um método dele que realmente será feito o lookup. Porém fazendo um debug ele está fazendo o lookup do EJB duas vezes: uma quando retorno o proxy e outra quando eu realmente uso o EJB.

O certo ele deveria fazer lookup apenas quando eu usar o EJB, e não nesses dois momnetos citados acima. Alguém que já usou cglib sabe como resolver?

public final class ServiceLocator {

    public static <T> T getEJB(Class<T> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setInterfaces(new Class[] { clazz });
        enhancer.setCallback(new Interceptor(clazz));
        return (T) enhancer.create();
    }

    private static class Interceptor
        implements MethodInterceptor {

        final Class<?> clazz;

        public Interceptor(Class<?> clazz) {
            this.clazz = clazz;
        }

        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
            throws Throwable {
            try {
                return method.invoke(doGetEJB(clazz), args);
            } catch (InvocationTargetException ex) {
                throw ex.getTargetException();
            }
        }

        private Object doGetEJB(Class<?> clazz) {
            try {
                logger.debug("trying lookup");
                Object instance = ctx.lookup(clazz.getName());
                logger.debug("lookup ok, {}", instance);
				
                return instance;
            } catch (NamingException e) {
                throw new InfraestructureException(e);
            }
        }
    }
}

1 Resposta

G

Enfim, resolvido. Na verdade era o profiler que eu estava usando para detectar melhor performance estava chamando o toString, chamando assim duas vezes o método.

Porém há outro problema agora: como rodo o glassfish em modo cluster, o proxy algumas vezes não consegue mais efetuar o lookup. Quando eu rodo em instância única do glassfish isso não acontece.

SEVERE: NAM0002: Exception in NamingManagerImpl copyMutableObject(). java.lang.IllegalArgumentException: Illegal null argument to ObjectInputStreamWithLoader at com.sun.enterprise.util.ObjectInputStreamWithLoader.<init>(ObjectInputStreamWithLoader.java:61) at com.sun.enterprise.naming.NamingUtils.makeCopyOfObject(NamingUtils.java:73) at com.sun.enterprise.naming.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:128) at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:409) at javax.naming.InitialContext.lookup(InitialContext.java:392) at esim.web.application.ServiceLocator$Interceptor.doGetEJB(ServiceLocator.java:103) at esim.web.application.ServiceLocator$Interceptor.intercept(ServiceLocator.java:87) at esim.model.service.SettingService$$EnhancerByCGLIB$$1b15e1ea.finalize(<generated>) at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method) at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83) at java.lang.ref.Finalizer.access$100(Finalizer.java:14) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)

Criado 27 de outubro de 2009
Ultima resposta 27 de out. de 2009
Respostas 1
Participantes 1