From 309cc66e50aaac713a5c2c72e3ea6b236716b036 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Fri, 5 Aug 2016 13:24:03 +0100 Subject: Scan for methods in extra interface hierarchy The ProxyBuilder was not traversing the interface hierarchy of the extra interfaces provided by the caller to find methods to proxy. That resulted in an AbstractMethodError when those methods were called. (cherry picked from d6b8d02d4fc7d57f0b72dba598b6320ef02a8213) Bug: 36407367 Bug: 32912773 Test: Added a failing test then fixed it, reran tests Change-Id: If68105da3b7e62383c8fa8ececc21383b299d854 --- .../src/main/java/com/android/dx/stock/ProxyBuilder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'dexmaker') 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 1daf8e3..b618c84 100644 --- a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java +++ b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java @@ -632,9 +632,13 @@ public final class ProxyBuilder { private Method[] getMethodsToProxyRecursive() { Set methodsToProxy = new HashSet<>(); Set seenFinalMethods = new HashSet<>(); + // Traverse the class hierarchy to ensure that all concrete methods (which could be marked + // as final) are visited before any abstract methods from interfaces. for (Class c = baseClass; c != null; c = c.getSuperclass()) { getMethodsToProxy(methodsToProxy, seenFinalMethods, c); } + // Now traverse the interface hierarchy, starting with the ones implemented by the class, + // followed by any extra interfaces. for (Class c = baseClass; c != null; c = c.getSuperclass()) { for (Class i : c.getInterfaces()) { getMethodsToProxy(methodsToProxy, seenFinalMethods, i); @@ -710,6 +714,14 @@ public final class ProxyBuilder { } sink.add(entry); } + + // Only visit the interfaces of this class if it is itself an interface. That prevents + // visiting interfaces of a class before its super classes. + if (c.isInterface()) { + for (Class i : c.getInterfaces()) { + getMethodsToProxy(sink, seenFinalMethods, i); + } + } } private static String getMethodNameForProxyOf(Class clazz) { -- cgit v1.2.3