diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java index 42cd8c5c726..73bb314350b 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java @@ -21,10 +21,11 @@ package org.apache.cloudstack.framework.async; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; -import net.sf.cglib.proxy.Callback; -import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; @@ -35,53 +36,72 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { private static final Logger s_logger = Logger.getLogger(AsyncCallbackDispatcher.class); private Method _callbackMethod; - private final T _targetObject; - private Object _contextObject; - private Object _resultObject; - private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver(); + private final T _targetObject; + private Object _contextObject; + private Object _resultObject; + private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver(); + private static Map enMap = new HashMap(); - private AsyncCallbackDispatcher(T target) { - assert(target != null); - _targetObject = target; - } + private AsyncCallbackDispatcher(T target) { + assert (target != null); + _targetObject = target; + } - public AsyncCallbackDispatcher attachDriver(AsyncCallbackDriver driver) { - assert(driver != null); - _driver = driver; + public AsyncCallbackDispatcher attachDriver(AsyncCallbackDriver driver) { + assert (driver != null); + _driver = driver; - return this; - } + return this; + } - public Method getCallbackMethod() { - return _callbackMethod; - } + public Method getCallbackMethod() { + return _callbackMethod; + } - @SuppressWarnings("unchecked") - public T getTarget() { - Enhancer en = new Enhancer(); + @SuppressWarnings("unchecked") + public T getTarget() { + Class clz = _targetObject.getClass(); + String clzName = clz.getName(); + if (clzName.contains("EnhancerByCloudStack")) + clz = clz.getSuperclass(); - Class clz = _targetObject.getClass(); - String clzName = clz.getName(); - if(clzName.contains("EnhancerByCloudStack")) - clz = clz.getSuperclass(); - en.setSuperclass(clz); - en.setCallbacks(new Callback[]{new MethodInterceptor() { - @Override - public Object intercept(Object arg0, Method arg1, Object[] arg2, - MethodProxy arg3) throws Throwable { - _callbackMethod = arg1; - _callbackMethod.setAccessible(true); - return null; - } - }, - new MethodInterceptor() { - @Override - public Object intercept(Object arg0, Method arg1, Object[] arg2, - MethodProxy arg3) throws Throwable { - return null; + Enhancer en = null; + synchronized (enMap) { + en = enMap.get(clz); + if (en == null) { + en = new Enhancer(); + + en.setSuperclass(clz); + en.setCallback(new MethodInterceptor() { + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { + return null; + } + }); + enMap.put(clz, en); } } + + try { + T t = (T)en.create(); + Factory factory = (Factory)t; + factory.setCallback(0, new MethodInterceptor() { + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { + if (arg1.getParameterTypes().length == 0 && arg1.getName().equals("finalize")) { + return null; + } else { + _callbackMethod = arg1; + _callbackMethod.setAccessible(true); + return null; + } + } + }); + return t; + } catch (Throwable e) { + s_logger.error("Unexpected exception", e); + } }); en.setCallbackFilter(new CallbackFilter() { @Override