diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2013-04-11 15:21:33 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2013-04-11 15:21:33 +0000 |
commit | 91f6abdd9e1e637251e9bfae381afc0c6a47c1b9 (patch) | |
tree | 28aeea8615a488c2f2372c345e78c20e5e9682fb /src/main/javassist | |
parent | fba928ea9f16486ad07c9f48fbc7c021ca5535a9 (diff) | |
download | javassist-91f6abdd9e1e637251e9bfae381afc0c6a47c1b9.tar.gz javassist-91f6abdd9e1e637251e9bfae381afc0c6a47c1b9.zip |
fixed JASSIST-162 and JASSIST-189
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@701 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist')
-rw-r--r-- | src/main/javassist/bytecode/ClassFile.java | 5 | ||||
-rw-r--r-- | src/main/javassist/util/proxy/ProxyFactory.java | 40 |
2 files changed, 31 insertions, 14 deletions
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java index 307cc0e8..a7d53fc9 100644 --- a/src/main/javassist/bytecode/ClassFile.java +++ b/src/main/javassist/bytecode/ClassFile.java @@ -690,12 +690,15 @@ public final class ClassFile { if (notBridgeMethod(minfo)) return true; else { + // if the bridge method with the same signature + // already exists, replace it. it.remove(); return false; } } else - return notBridgeMethod(minfo) && notBridgeMethod(newMethod); + return false; + // return notBridgeMethod(minfo) && notBridgeMethod(newMethod); } /* For a bridge method, see Sec. 15.12.4.5 of JLS 3rd Ed. diff --git a/src/main/javassist/util/proxy/ProxyFactory.java b/src/main/javassist/util/proxy/ProxyFactory.java index 957ba8f1..88636c01 100644 --- a/src/main/javassist/util/proxy/ProxyFactory.java +++ b/src/main/javassist/util/proxy/ProxyFactory.java @@ -800,9 +800,9 @@ public class ProxyFactory { { checkClassAndSuperName(); + hasGetHandler = false; // getMethods() may set this to true. HashMap allMethods = getMethods(superClass, interfaces); signatureMethods = new ArrayList(allMethods.entrySet()); - hasGetHandler = allMethods.get(HANDLER_GETTER_KEY) != null; Collections.sort(signatureMethods, sorter); } @@ -981,17 +981,22 @@ public class ProxyFactory { Map.Entry e = (Map.Entry)it.next(); String key = (String)e.getKey(); Method meth = (Method)e.getValue(); - int mod = meth.getModifiers(); - if (testBit(signature, index)) { - override(className, meth, prefix, index, - keyToDesc(key, meth), cf, cp, forwarders); - } + if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_5 || !isBridge(meth)) + if (testBit(signature, index)) { + override(className, meth, prefix, index, + keyToDesc(key, meth), cf, cp, forwarders); + } + index++; } return index; } + private static boolean isBridge(Method m) { + return m.isBridge(); + } + private void override(String thisClassname, Method meth, String prefix, int index, String desc, ClassFile cf, ConstPool cp, ArrayList forwarders) throws CannotCompileException @@ -1083,7 +1088,9 @@ public class ProxyFactory { return name.substring(0, i); } - private static HashMap getMethods(Class superClass, Class[] interfaceTypes) { + /* getMethods() may set hasGetHandler to true. + */ + private HashMap getMethods(Class superClass, Class[] interfaceTypes) { HashMap hash = new HashMap(); HashSet set = new HashSet(); for (int i = 0; i < interfaceTypes.length; i++) @@ -1093,7 +1100,7 @@ public class ProxyFactory { return hash; } - private static void getMethods(HashMap hash, Class clazz, Set visitedClasses) { + private void getMethods(HashMap hash, Class clazz, Set visitedClasses) { // This both speeds up scanning by avoiding duplicate interfaces and is needed to // ensure that superinterfaces are always scanned before subinterfaces. if (!visitedClasses.add(clazz)) @@ -1107,12 +1114,19 @@ public class ProxyFactory { if (parent != null) getMethods(hash, parent, visitedClasses); + /* Java 5 or later allows covariant return types. + * It also allows contra-variant parameter types + * if a super class is a generics with concrete type arguments + * such as Foo<String>. So the method-overriding rule is complex. + */ Method[] methods = SecurityActions.getDeclaredMethods(clazz); for (int i = 0; i < methods.length; i++) if (!Modifier.isPrivate(methods[i].getModifiers())) { Method m = methods[i]; - // JIRA JASSIST-127 (covariant return types). - String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m.getParameterTypes(), null); + String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m); // see keyToDesc(). + if (key.startsWith(HANDLER_GETTER_KEY)) + hasGetHandler = true; + // JIRA JASSIST-85 // put the method to the cache, retrieve previous definition (if any) Method oldMethod = (Method)hash.put(key, methods[i]); @@ -1127,11 +1141,11 @@ public class ProxyFactory { } } - private static final String HANDLER_GETTER_KEY = HANDLER_GETTER + ":()"; + private static final String HANDLER_GETTER_KEY + = HANDLER_GETTER + ":()"; private static String keyToDesc(String key, Method m) { - String params = key.substring(key.indexOf(':') + 1); - return RuntimeSupport.makeDescriptor(params, m.getReturnType()); + return key.substring(key.indexOf(':') + 1); } private static MethodInfo makeConstructor(String thisClassName, Constructor cons, |