Update DexMaker's UnsafeAllocator
Bug: 8297650
Change-Id: Icab2ac88926086070b1600e4514872d8b05de261
diff --git a/README b/README
index 270e5dd..5a1551c 100644
--- a/README
+++ b/README
@@ -14,5 +14,9 @@
It includes a stock code generator for class proxies. If you just want to do AOP or class mocking, you don't need to mess around with bytecodes.
Local Modifications:
-Patch to fix http://b/8108255 (Some mockito-based cannot be initialized due to a classloader issue), while Dexmaker's issue #20 (https://code.google.com/p/dexmaker/issues/detail?id=20) is not fixed.
+bug-8108255.patch: temporary workaround to ClassLoading issues
+ (see https://code.google.com/p/dexmaker/issues/detail?id=20)
+bug-8297650.patch: temporary workaround for a breakage in object instantiation
+ (see https://code.google.com/p/dexmaker/issues/detail?id=22)
+
(to apply, run 'patch -p0 < bug-xyz.patch' from a fresh src)
diff --git a/bug-8297650.patch b/bug-8297650.patch
new file mode 100644
index 0000000..59d4d32
--- /dev/null
+++ b/bug-8297650.patch
@@ -0,0 +1,39 @@
+--- src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java
++++ src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java
+@@ -92,6 +92,29 @@ abstract class UnsafeAllocator {
+ } catch (Exception ignored) {
+ }
+
++ // try dalvikvm, with change https://android-review.googlesource.com/#/c/52331/
++ // public class ObjectStreamClass {
++ // private static native long getConstructorId(Class<?> c);
++ // private static native Object newInstance(Class<?> instantiationClass, long methodId);
++ // }
++ try {
++ Method getConstructorId = ObjectStreamClass.class
++ .getDeclaredMethod("getConstructorId", Class.class);
++ getConstructorId.setAccessible(true);
++ final long constructorId = (Long) getConstructorId.invoke(null, Object.class);
++ final Method newInstance = ObjectStreamClass.class
++ .getDeclaredMethod("newInstance", Class.class, long.class);
++ newInstance.setAccessible(true);
++ return new UnsafeAllocator() {
++ @Override
++ @SuppressWarnings("unchecked")
++ public <T> T newInstance(Class<T> c) throws Exception {
++ return (T) newInstance.invoke(null, c, constructorId);
++ }
++ };
++ } catch (Exception ignored) {
++ }
++
+ // give up
+ return new UnsafeAllocator() {
+ @Override
+@@ -100,4 +123,4 @@ abstract class UnsafeAllocator {
+ }
+ };
+ }
+-}
+\ No newline at end of file
++}
diff --git a/src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java b/src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java
index 2e10b41..15e0324 100644
--- a/src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java
+++ b/src/mockito/java/com/google/dexmaker/mockito/UnsafeAllocator.java
@@ -92,6 +92,29 @@
} catch (Exception ignored) {
}
+ // try dalvikvm, with change https://android-review.googlesource.com/#/c/52331/
+ // public class ObjectStreamClass {
+ // private static native long getConstructorId(Class<?> c);
+ // private static native Object newInstance(Class<?> instantiationClass, long methodId);
+ // }
+ try {
+ Method getConstructorId = ObjectStreamClass.class
+ .getDeclaredMethod("getConstructorId", Class.class);
+ getConstructorId.setAccessible(true);
+ final long constructorId = (Long) getConstructorId.invoke(null, Object.class);
+ final Method newInstance = ObjectStreamClass.class
+ .getDeclaredMethod("newInstance", Class.class, long.class);
+ newInstance.setAccessible(true);
+ return new UnsafeAllocator() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T> T newInstance(Class<T> c) throws Exception {
+ return (T) newInstance.invoke(null, c, constructorId);
+ }
+ };
+ } catch (Exception ignored) {
+ }
+
// give up
return new UnsafeAllocator() {
@Override
@@ -100,4 +123,4 @@
}
};
}
-}
\ No newline at end of file
+}