aboutsummaryrefslogtreecommitdiff
path: root/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java')
-rw-r--r--dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java31
1 files changed, 23 insertions, 8 deletions
diff --git a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
index d82f8c4..1daf8e3 100644
--- a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
+++ b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
@@ -248,10 +248,20 @@ public final class ProxyBuilder<T> {
// we only populate the map with matching types
@SuppressWarnings("unchecked")
Class<? extends T> proxyClass = (Class) generatedProxyClasses.get(baseClass);
- if (proxyClass != null
- && proxyClass.getClassLoader().getParent() == parentClassLoader
- && interfaces.equals(asSet(proxyClass.getInterfaces()))) {
- return proxyClass; // cache hit!
+ if (proxyClass != null) {
+ boolean shareClassLoader = Boolean.parseBoolean(System.getProperty(
+ "dexmaker.share_classloader", "false"));
+ boolean validClassLoader;
+ if (shareClassLoader) {
+ ClassLoader parent = parentClassLoader != null ? parentClassLoader
+ : baseClass.getClassLoader();
+ validClassLoader = proxyClass.getClassLoader() == parent;
+ } else {
+ validClassLoader = proxyClass.getClassLoader().getParent() == parentClassLoader;
+ }
+ if (validClassLoader && interfaces.equals(asSet(proxyClass.getInterfaces()))) {
+ return proxyClass; // cache hit!
+ }
}
// the cache missed; generate the class
@@ -263,7 +273,8 @@ public final class ProxyBuilder<T> {
Method[] methodsToProxy = getMethodsToProxyRecursive();
generateCodeForAllMethods(dexMaker, generatedType, methodsToProxy, superType);
dexMaker.declare(generatedType, generatedName + ".generated", PUBLIC, superType, getInterfacesAsTypeIds());
- ClassLoader classLoader = dexMaker.generateAndLoad(parentClassLoader, dexCache);
+ ClassLoader classLoader = dexMaker.generateAndLoad(baseClass.getClassLoader(),
+ parentClassLoader, dexCache);
try {
proxyClass = loadClass(classLoader, generatedName);
} catch (IllegalAccessError e) {
@@ -653,6 +664,8 @@ public final class ProxyBuilder<T> {
private void getMethodsToProxy(Set<MethodSetEntry> sink, Set<MethodSetEntry> seenFinalMethods,
Class<?> c) {
+ boolean shareClassLoader = Boolean.parseBoolean(System.getProperty(
+ "dexmaker.share_classloader", "false"));
for (Method method : c.getDeclaredMethods()) {
if ((method.getModifiers() & Modifier.FINAL) != 0) {
// Skip final methods, we can't override them. We
@@ -670,13 +683,15 @@ public final class ProxyBuilder<T> {
continue;
}
if (!Modifier.isPublic(method.getModifiers())
- && !Modifier.isProtected(method.getModifiers())) {
+ && !Modifier.isProtected(method.getModifiers())
+ && (!shareClassLoader || Modifier.isPrivate(method.getModifiers()))) {
// Skip private methods, since they are invoked through direct
// invocation (as opposed to virtual). Therefore, it would not
// be possible to intercept any private method defined inside
// the proxy class except through reflection.
- // Skip package-private methods as well. The proxy class does
+ // Skip package-private methods as well (for non-shared class
+ // loaders). The proxy class does
// not actually inherit package-private methods from the parent
// class because it is not a member of the parent's package.
// This is even true if the two classes have the same package
@@ -698,7 +713,7 @@ public final class ProxyBuilder<T> {
}
private static <T> String getMethodNameForProxyOf(Class<T> clazz) {
- return clazz.getSimpleName() + "_Proxy";
+ return clazz.getName().replace(".", "/") + "_Proxy";
}
private static TypeId<?>[] classArrayToTypeArray(Class<?>[] input) {