From e3f71eadc205f4346f6a97b44820df40490f5c4b Mon Sep 17 00:00:00 2001 From: Hugo Hudson Date: Tue, 27 Mar 2012 12:20:47 +0100 Subject: Update to r17 of LittleMock. Change-Id: I7a9468b8c73e592eb75f28aed2268171eae70308 --- src/com/google/testing/littlemock/LittleMock.java | 134 ++++++++++++---------- 1 file changed, 73 insertions(+), 61 deletions(-) (limited to 'src/com/google/testing/littlemock/LittleMock.java') diff --git a/src/com/google/testing/littlemock/LittleMock.java b/src/com/google/testing/littlemock/LittleMock.java index 9d756dc..ee589db 100644 --- a/src/com/google/testing/littlemock/LittleMock.java +++ b/src/com/google/testing/littlemock/LittleMock.java @@ -1140,6 +1140,15 @@ public class LittleMock { throw new IllegalArgumentException("not a valid mock: " + mock); } + private static boolean canUseJavassist() { + try { + Class.forName("javassist.util.proxy.ProxyFactory"); + return true; + } catch (Exception expectedIfNotJavassistProxy) { + return false; + } + } + /** Create a dynamic proxy for the given class, delegating to the given invocation handler. */ private static Object createProxy(Class clazz, final InvocationHandler handler) { // Interfaces are simple. Just proxy them using java.lang.reflect.Proxy. @@ -1147,68 +1156,71 @@ public class LittleMock { return Proxy.newProxyInstance(getClassLoader(), new Class[] { clazz }, handler); } // Try with javassist. - try { - Class proxyFactoryClass = Class.forName("javassist.util.proxy.ProxyFactory"); - Object proxyFactory = proxyFactoryClass.newInstance(); - Method setSuperclassMethod = proxyFactoryClass.getMethod("setSuperclass", Class.class); - setSuperclassMethod.invoke(proxyFactory, clazz); - Class methodFilterClass = Class.forName("javassist.util.proxy.MethodFilter"); - InvocationHandler methodFilterHandler = new InvocationHandler() { - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - checkState(method.getName().equals("isHandled")); - checkState(args.length == 1); - checkState(args[0] instanceof Method); - Method invokedMethod = (Method) args[0]; - String methodName = invokedMethod.getName(); - Class[] params = invokedMethod.getParameterTypes(); - if ("equals".equals(methodName) && params.length == 1 - && Object.class.equals(params[0])) { - return false; - } - if ("hashCode".equals(methodName) && params.length == 0) { - return false; - } - if ("toString".equals(methodName) && params.length == 0) { - return false; - } - if ("finalize".equals(methodName) && params.length == 0) { - return false; - } - return true; - } - }; - Object methodFilter = Proxy.newProxyInstance(getClassLoader(), - new Class[] { methodFilterClass }, methodFilterHandler); - Method setFilterMethod = proxyFactoryClass.getMethod("setFilter", methodFilterClass); - setFilterMethod.invoke(proxyFactory, methodFilter); - Method createClassMethod = proxyFactoryClass.getMethod("createClass"); - Class createdClass = (Class) createClassMethod.invoke(proxyFactory); - InvocationHandler methodHandlerHandler = new InvocationHandler() { - @SuppressWarnings("unused") - public InvocationHandler $$getOriginal() { - return handler; + if (canUseJavassist()) { + try { + Class proxyFactoryClass = Class.forName("javassist.util.proxy.ProxyFactory"); + Object proxyFactory = proxyFactoryClass.newInstance(); + Method setSuperclassMethod = proxyFactoryClass.getMethod("setSuperclass", Class.class); + setSuperclassMethod.invoke(proxyFactory, clazz); + Class methodFilterClass = Class.forName("javassist.util.proxy.MethodFilter"); + InvocationHandler methodFilterHandler = new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + checkState(method.getName().equals("isHandled")); + checkState(args.length == 1); + checkState(args[0] instanceof Method); + Method invokedMethod = (Method) args[0]; + String methodName = invokedMethod.getName(); + Class[] params = invokedMethod.getParameterTypes(); + if ("equals".equals(methodName) && params.length == 1 + && Object.class.equals(params[0])) { + return false; + } + if ("hashCode".equals(methodName) && params.length == 0) { + return false; + } + if ("toString".equals(methodName) && params.length == 0) { + return false; + } + if ("finalize".equals(methodName) && params.length == 0) { + return false; + } + return true; + } + }; + Object methodFilter = Proxy.newProxyInstance(getClassLoader(), + new Class[] { methodFilterClass }, methodFilterHandler); + Method setFilterMethod = proxyFactoryClass.getMethod("setFilter", methodFilterClass); + setFilterMethod.invoke(proxyFactory, methodFilter); + Method createClassMethod = proxyFactoryClass.getMethod("createClass"); + Class createdClass = (Class) createClassMethod.invoke(proxyFactory); + InvocationHandler methodHandlerHandler = new InvocationHandler() { + @SuppressWarnings("unused") + public InvocationHandler $$getOriginal() { + return handler; + } + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + checkState(method.getName().equals("invoke")); + checkState(args.length == 4); + checkState(args[1] instanceof Method); + Method invokedMethod = (Method) args[1]; + checkState(args[3] instanceof Object[]); + return handler.invoke(args[0], invokedMethod, (Object[]) args[3]); + } + }; + Class methodHandlerClass = Class.forName("javassist.util.proxy.MethodHandler"); + Object methodHandler = Proxy.newProxyInstance(getClassLoader(), + new Class[] { methodHandlerClass }, methodHandlerHandler); + Object proxy = unsafeCreateInstance(createdClass); + Class proxyObjectClass = Class.forName("javassist.util.proxy.ProxyObject"); + Method setHandlerMethod = proxyObjectClass.getMethod("setHandler", methodHandlerClass); + setHandlerMethod.invoke(proxy, methodHandler); + return proxy; + } catch (Exception e) { + // Not supported, something went wrong. Fall through, try android dexmaker. + e.printStackTrace(System.err); } - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - checkState(method.getName().equals("invoke")); - checkState(args.length == 4); - checkState(args[1] instanceof Method); - Method invokedMethod = (Method) args[1]; - checkState(args[3] instanceof Object[]); - return handler.invoke(args[0], invokedMethod, (Object[]) args[3]); - } - }; - Class methodHandlerClass = Class.forName("javassist.util.proxy.MethodHandler"); - Object methodHandler = Proxy.newProxyInstance(getClassLoader(), - new Class[] { methodHandlerClass }, methodHandlerHandler); - Object proxy = unsafeCreateInstance(createdClass); - Class proxyObjectClass = Class.forName("javassist.util.proxy.ProxyObject"); - Method setHandlerMethod = proxyObjectClass.getMethod("setHandler", methodHandlerClass); - setHandlerMethod.invoke(proxy, methodHandler); - return proxy; - } catch (Exception e) { - // Not supported, i.e. javassist missing. Fall through. } // So, this is a class. First try using Android's ProxyBuilder from dexmaker. try { -- cgit v1.2.3