Author: timothyjward Date: Mon Sep 19 09:34:40 2016 New Revision: 1761408 URL: http://svn.apache.org/viewvc?rev=1761408&view=rev Log: ARIES-1603 Ensure mediator cache is populated, and add tests
Modified: aries/trunk/async/async-impl/src/main/java/org/apache/aries/async/impl/AsyncService.java aries/trunk/async/async-impl/src/test/java/org/apache/aries/async/impl/AsyncServiceTest.java Modified: aries/trunk/async/async-impl/src/main/java/org/apache/aries/async/impl/AsyncService.java URL: http://svn.apache.org/viewvc/aries/trunk/async/async-impl/src/main/java/org/apache/aries/async/impl/AsyncService.java?rev=1761408&r1=1761407&r2=1761408&view=diff ============================================================================== --- aries/trunk/async/async-impl/src/main/java/org/apache/aries/async/impl/AsyncService.java (original) +++ aries/trunk/async/async-impl/src/main/java/org/apache/aries/async/impl/AsyncService.java Mon Sep 19 09:34:40 2016 @@ -38,7 +38,9 @@ import org.osgi.service.log.LogService; import org.osgi.util.promise.Promise; import org.osgi.util.tracker.ServiceTracker; +import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.Factory; public class AsyncService implements Async { @@ -113,18 +115,23 @@ public class AsyncService implements Asy TrackingInvocationHandler handler = new TrackingInvocationHandler(this, clientBundle, logServiceTracker, service); - T toReturn = cachedMediate(iface, handler); + synchronized(proxyLoaderCache) { + T toReturn = cachedMediate(iface, handler); - if(toReturn != null) { - return toReturn; - } else if(iface.isInterface()) { - return (T) Proxy.newProxyInstance( + if(toReturn != null) { + return toReturn; + } else if(iface.isInterface()) { + toReturn = (T) Proxy.newProxyInstance( new ClassLoader(service.getClass().getClassLoader()){}, new Class[] {iface}, handler); - } else { - return (T) proxyClass(iface, handler, + } else { + toReturn = (T) proxyClass(iface, handler, new CGLibAwareClassLoader(service.getClass().getClassLoader())); - } + } + proxyLoaderCache.put(iface, new WeakReference<Class<?>>(toReturn.getClass())); + + return toReturn; + } } @SuppressWarnings("unchecked") @@ -140,7 +147,13 @@ public class AsyncService implements Asy throw new IllegalArgumentException("Unable to mediate interface: " + iface, e); } } else { - return (T) Enhancer.create(cached, handler); + try { + T t = (T) cached.getConstructor().newInstance(); + ((Factory)t).setCallbacks(new Callback[] {handler}); + return t; + } catch (Exception e) { + throw new IllegalArgumentException("Unable to mediate class: " + iface, e); + } } } return null; @@ -160,18 +173,23 @@ public class AsyncService implements Asy TrackingInvocationHandler handler = new TrackingInvocationHandler(this, clientBundle, logServiceTracker, ref); - T toReturn = cachedMediate(iface, handler); - - if(toReturn != null) { - return toReturn; - } else if(iface.isInterface()) { - return (T) Proxy.newProxyInstance( + synchronized(proxyLoaderCache) { + T toReturn = cachedMediate(iface, handler); + + if(toReturn != null) { + return toReturn; + } else if(iface.isInterface()) { + toReturn = (T) Proxy.newProxyInstance( new ClassLoader(iface.getClassLoader()){}, new Class[] {iface}, handler); - } else { - return (T) proxyClass(iface, handler, + } else { + toReturn = (T) proxyClass(iface, handler, new CGLibAwareClassLoader(iface.getClassLoader())); - } + } + proxyLoaderCache.put(iface, new WeakReference<Class<?>>(toReturn.getClass())); + + return toReturn; + } } private Object proxyClass(Class<?> mostSpecificClass, Modified: aries/trunk/async/async-impl/src/test/java/org/apache/aries/async/impl/AsyncServiceTest.java URL: http://svn.apache.org/viewvc/aries/trunk/async/async-impl/src/test/java/org/apache/aries/async/impl/AsyncServiceTest.java?rev=1761408&r1=1761407&r2=1761408&view=diff ============================================================================== --- aries/trunk/async/async-impl/src/test/java/org/apache/aries/async/impl/AsyncServiceTest.java (original) +++ aries/trunk/async/async-impl/src/test/java/org/apache/aries/async/impl/AsyncServiceTest.java Mon Sep 19 09:34:40 2016 @@ -18,6 +18,7 @@ */ package org.apache.aries.async.impl; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.concurrent.CountDownLatch; @@ -103,4 +104,28 @@ public class AsyncServiceTest { assertTrue(latch.await(5, TimeUnit.SECONDS)); } + @Test + public void testMultipleMediationsCacheClassLoader() throws Exception { + DelayedEcho raw = new DelayedEcho(); + + AsyncService service = new AsyncService(null, es, + serviceTracker); + + DelayedEcho mediated = service.mediate(raw, DelayedEcho.class); + + assertSame(mediated.getClass(), service.mediate(raw, DelayedEcho.class).getClass()); + } + + @Test + public void testMultipleMediationsCacheClassLoaderInterface() throws Exception { + CharSequence raw = "test"; + + AsyncService service = new AsyncService(null, es, + serviceTracker); + + CharSequence mediated = service.mediate(raw, CharSequence.class); + + assertSame(mediated.getClass(), service.mediate(raw, CharSequence.class).getClass()); + } + }