package pl.ibpolsoft.sop.client.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.logging.Logger; import javax.ejb.NoSuchEJBException; import pl.ibpolsoft.toolkit.genericprovider.Provider; /** * * @author witoldsz */ public class EjbLookupRetryProvider implements InvocationHandler { private static final Object ERROR = new Object(); private final Logger logger = Logger.getLogger(EjbLookupRetryProvider.class.getName()); private final int maxTries = 2; private final Provider ejbLookupProvider; private final Class remoteInterface; private final String beanName; private Object bean = null; public EjbLookupRetryProvider(Provider ejbLookupProvider, ClassremoteInterface, String beanName) { this.ejbLookupProvider = ejbLookupProvider; this.remoteInterface = remoteInterface; this.beanName = beanName; } public EjbLookupRetryProvider(Provider ejbLookupProvider, ClassremoteInterface) { this( ejbLookupProvider,remoteInterface, ejbLookupProvider.create().defaultBeanName(remoteInterface) ); } public T getBean() { Object proxy = Proxy.newProxyInstance( remoteInterface.getClassLoader(), new Class[]{ remoteInterface }, this); return remoteInterface.cast(proxy); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = ERROR; Throwable throwable = null; for (int tryCnt = 1; tryCnt <= maxTries; tryCnt++) { logger.info(String.format( "try %d: Intercepting method %s, args:%s", tryCnt, method, Arrays.toString(args))); try { if (bean == null) { bean = ejbLookupProvider.create().getBean(remoteInterface, beanName); } result = method.invoke(bean, args); } catch (InvocationTargetException e) { throwable = handleException(e, tryCnt); bean = null; } if (result != ERROR) { return result; } } throw throwable; } private Throwable handleException(InvocationTargetException e, int tryCnt) { Throwable result = e.getCause(); if (result instanceof NoSuchEJBException) { logger.warning(String.format( "Got NoSuchEJBException when calling: %s. tryCnt=%d", beanName, tryCnt)); } return e.getCause(); } }