Merge "Update to r17 of LittleMock."
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 @@
     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 @@
       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;
+    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);
         }
-      };
-      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, i.e. javassist missing.  Fall through.
     }
     // So, this is a class.  First try using Android's ProxyBuilder from dexmaker.
     try {