From 8acd7ffa7eae1e72aa4884ed6ef921c6b812f71c Mon Sep 17 00:00:00 2001 From: Nate Fischer Date: Thu, 29 Mar 2018 21:36:13 +0000 Subject: AW: use correct ClassLoader in dupeMethod This fixes an issue with the support library where we would sometimes create an InvocationHandler and look up methods using the wrong ClassLoader. This ensures we always use the correct ClassLoader. dupeMethod() is only used here, so it's safe to change the signature. See the crbug for more information. Bug: 826988 Test: Manual, did this in my demo CL at http://crrev/c/965883 Change-Id: I7ca7bb90aec81a6a30ce4d6393cf40ee54d40c19 Reviewed-on: https://chromium-review.googlesource.com/985631 Reviewed-by: Richard Coles Commit-Queue: Nate Fischer Cr-Original-Commit-Position: refs/heads/master@{#546961} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: c6aed4c0fe3d8eeb3ae7f2bdd32cc6433cdf929c --- .../util/BoundaryInterfaceReflectionUtil.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java b/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java index 5a772c5..51c78ed 100644 --- a/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java +++ b/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java @@ -16,13 +16,14 @@ import java.lang.reflect.Proxy; */ public class BoundaryInterfaceReflectionUtil { /** - * Utility method for fetching a method from the current classloader, with the same signature + * Utility method for fetching a method from {@param delegateLoader}, with the same signature * (package + class + method name + parameters) as a given method defined in another * classloader. */ - public static Method dupeMethod(Method method) + public static Method dupeMethod(Method method, ClassLoader delegateLoader) throws ClassNotFoundException, NoSuchMethodException { - Class declaringClass = Class.forName(method.getDeclaringClass().getName()); + Class declaringClass = + Class.forName(method.getDeclaringClass().getName(), true, delegateLoader); Class[] otherSideParameterClasses = method.getParameterTypes(); Class[] parameterClasses = new Class[otherSideParameterClasses.length]; for (int n = 0; n < parameterClasses.length; n++) { @@ -30,7 +31,9 @@ public class BoundaryInterfaceReflectionUtil { // Primitive classes are shared between the classloaders - so we can use the same // primitive class declarations on either side. Non-primitive classes must be looked up // by name. - parameterClasses[n] = clazz.isPrimitive() ? clazz : Class.forName(clazz.getName()); + parameterClasses[n] = clazz.isPrimitive() + ? clazz + : Class.forName(clazz.getName(), true, delegateLoader); } return declaringClass.getDeclaredMethod(method.getName(), parameterClasses); } @@ -53,11 +56,12 @@ public class BoundaryInterfaceReflectionUtil { */ @TargetApi(Build.VERSION_CODES.KITKAT) public static InvocationHandler createInvocationHandlerFor(final Object delegate) { + final ClassLoader delegateLoader = delegate.getClass().getClassLoader(); return new InvocationHandler() { @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { try { - return dupeMethod(method).invoke(delegate, objects); + return dupeMethod(method, delegateLoader).invoke(delegate, objects); } catch (InvocationTargetException e) { // If something went wrong, ensure we throw the original exception. throw e.getTargetException(); -- cgit v1.2.3