]> source.dussan.org Git - aspectj.git/commitdiff
some bridge method testcases and impl for 108101
authoraclement <aclement>
Tue, 25 Oct 2005 11:17:21 +0000 (11:17 +0000)
committeraclement <aclement>
Tue, 25 Oct 2005 11:17:21 +0000 (11:17 +0000)
tests/java5/generics/itds/bridgeMethods/Sub4.java [new file with mode: 0644]
tests/java5/generics/itds/bridgeMethods/Super4.java [new file with mode: 0644]
tests/java5/generics/itds/bridgeMethods/X1.aj
tests/java5/generics/itds/bridgeMethods/X2.aj
tests/java5/generics/itds/bridgeMethods/X3.aj
tests/java5/generics/itds/bridgeMethods/X4.aj [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java

diff --git a/tests/java5/generics/itds/bridgeMethods/Sub4.java b/tests/java5/generics/itds/bridgeMethods/Sub4.java
new file mode 100644 (file)
index 0000000..ceff163
--- /dev/null
@@ -0,0 +1,3 @@
+public class Sub4 {
+  public Integer m() {return new Integer(42);}
+}
diff --git a/tests/java5/generics/itds/bridgeMethods/Super4.java b/tests/java5/generics/itds/bridgeMethods/Super4.java
new file mode 100644 (file)
index 0000000..cd4237a
--- /dev/null
@@ -0,0 +1,3 @@
+public class Super4 {
+  public Object m() { return null;}
+}
index 2f085de6a60a42f52c7dcac861571b0ef339b111..5c5df61e290f3bcd6b48954922c417608cbd06b1 100644 (file)
@@ -2,7 +2,5 @@ public aspect X1 {
   public static void main(String []argv) {
     Super1 s = new Sub1();
     Integer i = (Integer)s.m();
-
-    Util.dumpMethods("Sub1");
   }
 }
index ce8f1a5424e4d9218e4f5e6aed80858e4d86c4df..11ea07c5cf20b89e109928d70e15c048d50c8f1a 100644 (file)
@@ -4,7 +4,5 @@ public aspect X2 {
   public static void main(String []argv) {
     Super2 s = new Sub2();
     Integer i = (Integer)s.m();
-    
-    Util.dumpMethods("Sub2");
   }
 }
index 5bd400d10bd8f4a53495cf94216d0f8a96b1ff95..e83af6b2641e4c48d1cfe77b31a05b9bdadb54a6 100644 (file)
@@ -5,7 +5,6 @@ public aspect X3 {
   public static void main(String []argv) {
     Super3 s = new Sub3();
     Integer i = (Integer)s.m();
-
-    Util.dumpMethods("Sub3");
+    if (i!=42) throw new RuntimeException("Should be 42 but is "+i);
   }
 }
diff --git a/tests/java5/generics/itds/bridgeMethods/X4.aj b/tests/java5/generics/itds/bridgeMethods/X4.aj
new file mode 100644 (file)
index 0000000..53333c8
--- /dev/null
@@ -0,0 +1,10 @@
+public aspect X4 {
+
+  declare parents: Sub4 extends Super4;
+
+  public static void main(String []argv) {
+    Super4 s = new Sub4();
+    Integer i = (Integer)s.m();
+    if (i!=42) throw new RuntimeException("Should be 42 but is "+i);
+  }
+}
index a3462950a40f6d437ed018e6cef48f831e499233..b61e75437f5101e9568916d7c616919bcf86b8d4 100644 (file)
@@ -1,6 +1,12 @@
 package org.aspectj.systemtest.ajc150;
 
 import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
 import junit.framework.Test;
 
@@ -405,12 +411,66 @@ public class GenericsTests extends XMLBasedAjcTestCase {
        public void testITDBridgeMethods2Itd()        {runTest("basic bridging with type vars - 2 - itd");}
        public void testITDBridgeMethodsPr91381() {runTest("Abstract intertype method and covariant returns");}
        
-    public void testGenericITDsBridgeMethods1()        {runTest("bridge methods - 1");}
-       public void testGenericITDsBridgeMethods1binary()  {runTest("bridge methods - 1 - binary");}
-       public void testGenericITDsBridgeMethods2()        {runTest("bridge methods - 2");}
-//     public void testGenericITDsBridgeMethods2binary()  {runTest("bridge methods - 2 - binary");} // pr108101
-       public void testGenericITDsBridgeMethods3()        {runTest("bridge methods - 3");}
-//     public void testGenericITDsBridgeMethods3binary()  {runTest("bridge methods - 3 - binary");} // pr108101
+       
+       // Just normal source compile of two types with a method override between them
+    public void testGenericITDsBridgeMethods1() {
+       runTest("bridge methods - 1");
+       checkMethodsExist("Sub1",new String[]{
+                       "java.lang.Integer Sub1.m()",
+                       "java.lang.Object Sub1.m() [BridgeMethod]"});
+    }
+    // Now the same thing but the aspect (which doesn't do much!) is binary woven in.
+       public void testGenericITDsBridgeMethods1binary()  {
+               runTest("bridge methods - 1 - binary");
+               checkMethodsExist("Sub1",new String[]{ 
+                               "java.lang.Integer Sub1.m()",
+                               "java.lang.Object Sub1.m() [BridgeMethod]"});
+       }
+       // Now the method is put into the superclass via ITD - there should be a bridge method in the subclass
+       public void testGenericITDsBridgeMethods2()        {
+               runTest("bridge methods - 2");
+               checkMethodsExist("Sub2",new String[]{
+                       "java.lang.Integer Sub2.m()",
+                       "java.lang.Object Sub2.m() [BridgeMethod]"});
+       }
+       // Now the superclass ITD is done with binary weaving so the weaver (rather than compiler) has to create the bridge method
+       public void testGenericITDsBridgeMethods2binary()  {
+               runTest("bridge methods - 2 - binary");
+               checkMethodsExist("Sub2",new String[]{
+                       "java.lang.Integer Sub2.m()",
+                       "java.lang.Object Sub2.m() [BridgeMethod]"});
+       }
+       // Now the method is put into the subclass via ITD - there should be a bridge method alongside it in the subclass
+       public void testGenericITDsBridgeMethods3()        {
+               runTest("bridge methods - 3");
+               checkMethodsExist("Sub3",new String[]{
+                       "java.lang.Integer Sub3.m()",
+                       "java.lang.Object Sub3.m() [BridgeMethod]"});
+       }
+       // Now the subclass ITD is done with binary weaving - the weaver should create the necessary bridge method
+//     public void testGenericITDsBridgeMethods3binary()  {
+//             runTest("bridge methods - 3 - binary");
+//             checkMethodsExist("Sub3",new String[]{
+//                     "java.lang.Integer Sub3.m()",
+//                     "java.lang.Object Sub3.m() [BridgeMethod]"});
+//     }
+       // Now the two types are disconnected until the aspect supplies a declare parents relationship - 
+       // the bridge method should still be created in the subtype
+       public void testGenericITDSBridgeMethods4() {
+               runTest("bridge methods - 4");
+               checkMethodsExist("Sub4",new String[]{
+                       "java.lang.Integer Sub4.m()",
+                               "java.lang.Object Sub4.m() [BridgeMethod]"});
+       }
+       // now the aspect doing the decp between the types is applied via binary weaving - weaver should create the bridge method
+//     public void testGenericITDSBridgeMethods4binary() {
+//             runTest("bridge methods - 4 - binary");
+//             checkMethodsExist("Sub4",new String[]{
+//                     "java.lang.Integer Sub4.m()",
+//                             "java.lang.Object Sub4.m() [BridgeMethod]"});
+//     }
+       
+       // FIXME asc need a testcase for when a decp wires two classes together and causes the subtype to need bridge methods
        
        public void testGenericITDsBridgeMethodsPR91381()  {runTest("abstract intertype methods and covariant returns");}
        public void testGenericITDsBridgeMethodsPR91381_2()  {runTest("abstract intertype methods and covariant returns - error");}
@@ -745,27 +805,77 @@ public class GenericsTests extends XMLBasedAjcTestCase {
        public void testMultiLevelGenericAspects() {
                runTest("multi-level generic abstract aspects");
        }
-       
        // --- helpers
+       
+       /**
+        * When a class has been written to the sandbox directory, you can ask this method to 
+        * verify it contains a particular set of methods.  Typically this is used to verify that
+        * bridge methods have been created.
+        */
+       public void checkMethodsExist(String classname,String[] methods) {
+               Set methodsFound = new HashSet();
+               StringBuffer debugString = new StringBuffer();
+               try {
+                       ClassLoader cl = new URLClassLoader(new URL[]{ajc.getSandboxDirectory().toURL()});
+                       Class clz = Class.forName(classname,false,cl);
+                       java.lang.reflect.Method[] ms = clz.getDeclaredMethods();
+                       if (ms!=null) {
+                               for (int i =0;i<ms.length;i++) {
+                                       String methodString = ms[i].getReturnType().getName()+" "+ms[i].getDeclaringClass().getName()+"."+
+                                                                  ms[i].getName()+"("+stringify(ms[i].getParameterTypes())+")"+
+                                                                  (ms[i].isBridge()?" [BridgeMethod]":"");
+                                       methodsFound.add(methodString);
+                                       debugString.append("[").append(methodString).append("]");
+                               }
+                       }
+               } catch (ClassNotFoundException e) {
+                       e.printStackTrace();
+               } catch (MalformedURLException e) {
+                       e.printStackTrace();
+               }
                
-       public static Signature getClassSignature(Ajc ajc,String classname) {
+               // check the methods specified do exist
+               for (int i = 0; i < methods.length; i++) {
+                       String string = methods[i];
+                       if (!methodsFound.remove(string)) {
+                               fail("Couldn't find ["+string+"] in the set of methods in "+classname+" => "+debugString);
+                       }
+               }
+               StringBuffer unexpectedMethods = new StringBuffer();
+               if (!methodsFound.isEmpty()) {
+                       for (Iterator iter = methodsFound.iterator(); iter.hasNext();) {
+                               String element = (String) iter.next();
+                               unexpectedMethods.append("[").append(element).append("]");
+                       }
+                       fail("These methods weren't expected: "+unexpectedMethods);
+               }
+               
+       }
+       
+       public static JavaClass getClass(Ajc ajc, String classname) {
                try {
                        ClassPath cp = 
                                new ClassPath(ajc.getSandboxDirectory() + File.pathSeparator + System.getProperty("java.class.path"));
                    SyntheticRepository sRepos =  SyntheticRepository.getInstance(cp);
                        JavaClass clazz = sRepos.loadClass(classname);
-                       Signature sigAttr = null;
-                       Attribute[] attrs = clazz.getAttributes();
-                       for (int i = 0; i < attrs.length; i++) {
-                               Attribute attribute = attrs[i];
-                               if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
-                       }
-                       return sigAttr;
+                       return clazz;
                } catch (ClassNotFoundException e) {
                        fail("Couldn't find class "+classname+" in the sandbox directory.");
                }
                return null;
        }
+               
+       public static Signature getClassSignature(Ajc ajc,String classname) {
+           JavaClass clazz = getClass(ajc,classname);
+               Signature sigAttr = null;
+               Attribute[] attrs = clazz.getAttributes();
+               for (int i = 0; i < attrs.length; i++) {
+                       Attribute attribute = attrs[i];
+                       if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
+               }
+               return sigAttr;
+       }
+       
        // Check the signature attribute on a class is correct
        public static void verifyClassSignature(Ajc ajc,String classname,String sig) {
                Signature sigAttr = getClassSignature(ajc,classname);
@@ -774,5 +884,15 @@ public class GenericsTests extends XMLBasedAjcTestCase {
                                sigAttr.getSignature().equals(sig));            
        }
                
+       private static String stringify(Class[] clazzes) {
+               if (clazzes==null) return "";
+               StringBuffer sb = new StringBuffer();
+               for (int i = 0; i < clazzes.length; i++) {
+                       Class class1 = clazzes[i];
+                       if (i>0) sb.append(",");
+                       sb.append(clazzes[i].getName());
+               }
+               return sb.toString();
+       }
 
 }
index 32eadcb051c9cff5e274eab2e5e5f5bf30408fd5..703204ab0e649a4d71674e24bac97ccf45e43bca 100644 (file)
    <!-- generics/itds and bridge methods -->
    
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 1">
-          <compile files="Sub1.java,Super1.java,X1.aj,Util.java" options="-1.5"/>
-       <run class="X1">
-         <stderr>
-           <line text="Number of methods defined for Sub1 is 2"/>
-           <line text="java.lang.Integer Sub1.m()"/>
-           <line text="java.lang.Object Sub1.m() [BridgeMethod]"/>
-         </stderr>
-       </run>
+          <compile files="Sub1.java,Super1.java,X1.aj" options="-1.5"/>
+       <run class="X1"/>
    </ajc-test>
-   
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 1 - binary">
         <compile files="Sub1.java,Super1.java" outjar="code.jar" options="-1.5"/>
-        <compile files="X1.aj,Util.java" inpath="code.jar" options ="-1.5"/>
-     <run class="X1">
-         <stderr>
-           <line text="Number of methods defined for Sub1 is 2"/>
-           <line text="java.lang.Integer Sub1.m()"/>
-           <line text="java.lang.Object Sub1.m() [BridgeMethod]"/>
-         </stderr>
-     </run>
+        <compile files="X1.aj" inpath="code.jar" options ="-1.5"/>
+     <run class="X1"/>
    </ajc-test>
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 2">
-          <compile files="Sub2.java,Super2.java,X2.aj,Util.java" options="-1.5"/>
-       <run class="X2">
-         <stderr>
-           <line text="Number of methods defined for Sub2 is 2"/>
-           <line text="java.lang.Integer Sub2.m()"/>
-           <line text="java.lang.Object Sub2.m() [BridgeMethod]"/>
-         </stderr>
-       </run>
+          <compile files="Sub2.java,Super2.java,X2.aj" options="-1.5"/>
+       <run class="X2"/>
    </ajc-test>
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 2 - binary">
         <compile files="Sub2.java,Super2.java" outjar="code.jar" options="-1.5"/>
         <compile files="X2.aj,Util.java" inpath="code.jar" options ="-1.5"/>
-     <run class="X2">
-         <stderr>
-           <line text="Number of methods defined for Sub2 is 2"/>
-           <line text="java.lang.Integer Sub2.m()"/>
-           <line text="java.lang.Object Sub2.m() [BridgeMethod]"/>
-         </stderr>
-     </run>
+     <run class="X2"/>
    </ajc-test>
       
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 3">
-        <compile files="Sub3.java,Super3.java,X3.aj,Util.java" options="-1.5"/>
-     <run class="X3">
-         <stderr>
-           <line text="Number of methods defined for Sub3 is 2"/>
-           <line text="java.lang.Integer Sub3.m()"/>
-           <line text="java.lang.Object Sub3.m() [BridgeMethod]"/>
-         </stderr>
-     </run>
+        <compile files="Sub3.java,Super3.java,X3.aj" options="-1.5"/>
+     <run class="X3"/>
    </ajc-test>
-   
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 3 - binary">
         <compile files="Sub3.java,Super3.java" outjar="code.jar" options="-1.5"/>
-        <compile files="X3.aj,Util.java" inpath="code.jar" options ="-1.5"/>
-     <run class="X3">
-         <stderr>
-           <line text="Number of methods defined for Sub3 is 2"/>
-           <line text="java.lang.Integer Sub3.m()"/>
-           <line text="java.lang.Object Sub3.m() [BridgeMethod]"/>
-         </stderr>
-     </run>
+        <compile files="X3.aj" inpath="code.jar" options ="-1.5"/>
+     <run class="X3"/>
+   </ajc-test>
+   
+   <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 4">
+        <compile files="Sub4.java,Super4.java,X4.aj" options="-1.5"/>
+     <run class="X4"/>
    </ajc-test>
+   <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 4 - binary">
+        <compile files="Sub4.java,Super4.java" outjar="code.jar" options="-1.5"/>
+        <compile files="X4.aj" inpath="code.jar" options ="-1.5"/>
+     <run class="X4"/>
+   </ajc-test>
+   
+   
       
    <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="abstract intertype methods and covariant returns">
           <compile files="pr91381.aj" options="-1.5"/>
index 36b65d38196df57cb6bdee1ce89515ba5b652601..3af5d3c9899d823e1317be7ef4d3f4d9677c880f 100644 (file)
@@ -735,13 +735,15 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                ResolvedMember memberHoldingAnyAnnotations = interMethodDispatcher;
                ResolvedType onType = weaver.getWorld().resolve(unMangledInterMethod.getDeclaringType(),munger.getSourceLocation());
                
-               LazyClassGen gen = weaver.getLazyClassGen();
-               boolean mungingInterface = gen.isInterface();
+               LazyClassGen             gen = weaver.getLazyClassGen();
+               boolean    mungingInterface = gen.isInterface();
                
                if (onType.isRawType()) onType = onType.getGenericType();
 
                boolean onInterface = onType.isInterface();
+
                
+               // Simple checks, can't ITD on annotations or enums
                if (onType.isAnnotation()) {
                        signalError(WeaverMessages.ITDM_ON_ANNOTATION_NOT_ALLOWED,weaver,onType);
                        return false;           
@@ -752,22 +754,26 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        return false;
                }
                
+               
+               
                if (onInterface && gen.getLazyMethodGen(unMangledInterMethod.getName(), unMangledInterMethod.getSignature(),true) != null) {
                                // this is ok, we could be providing the default implementation of a method
                                // that the target has already declared
                                return false;
                }
                
+               // If we are processing the intended ITD target type (might be an interface)
                if (onType.equals(gen.getType())) {
+                       
+                       
                        ResolvedMember mangledInterMethod =
                                        AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, onInterface);
             
-                       
-                       LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod);
+                       LazyMethodGen newMethod = makeMethodGen(gen, mangledInterMethod);
                        if (mungingInterface) {
                                // we want the modifiers of the ITD to be used for all *implementors* of the
                                // interface, but the method itself we add to the interface must be public abstract
-                               mg.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
+                               newMethod.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
                        }
                        
                        // pr98901
@@ -787,7 +793,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                                                AnnotationX annotationX = annotationsOnRealMember[i];
                                                Annotation a = annotationX.getBcelAnnotation();
                                                AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
-                                               mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
+                                               newMethod.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
                                        }
                                }
                                // the below loop fixes the very special (and very stupid)
@@ -797,14 +803,15 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                                for (Iterator i = allDecams.iterator(); i.hasNext();){
                                        DeclareAnnotation decaMC = (DeclareAnnotation) i.next();        
                                        if (decaMC.matches(unMangledInterMethod,weaver.getWorld())
-                                                       && mg.getEnclosingClass().getType() == aspectType) {
-                                               mg.addAnnotation(decaMC.getAnnotationX());
+                                                       && newMethod.getEnclosingClass().getType() == aspectType) {
+                                               newMethod.addAnnotation(decaMC.getAnnotationX());
                                        }
                                }
                        }
 
+                       // If it doesn't target an interface and there is a body (i.e. it isnt abstract)
                        if (!onInterface && !Modifier.isAbstract(mangledInterMethod.getModifiers())) {
-                               InstructionList body = mg.getBody();
+                               InstructionList body = newMethod.getBody();
                                InstructionFactory fact = gen.getFactory();
                                int pos = 0;
        
@@ -822,6 +829,11 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                                body.append(
                                        InstructionFactory.createReturn(
                                                BcelWorld.makeBcelType(mangledInterMethod.getReturnType())));
+                               
+                               if (weaver.getWorld().isInJava5Mode()) { // Don't need bridge methods if not in 1.5 mode.
+                                       createAnyBridgeMethodsForCovariance(weaver, munger, unMangledInterMethod, onType, gen, paramTypes);
+                               }
+                               
                        } else {
                                //??? this is okay
                                //if (!(mg.getBody() == null)) throw new RuntimeException("bas");
@@ -829,8 +841,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        
 
                        // XXX make sure to check that we set exceptions properly on this guy.
-                       weaver.addLazyMethodGen(mg);
-                       weaver.getLazyClassGen().warnOnAddedMethod(mg.getMethod(),getSignature().getSourceLocation());
+                       weaver.addLazyMethodGen(newMethod);
+                       weaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(),getSignature().getSourceLocation());
                        
                        addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
                        
@@ -896,6 +908,90 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        return false;
                }
        }
+
+       /**
+        * Create any bridge method required because of covariant returns being used.  This method is used in the case
+        * where an ITD is applied to some type and it may be in an override relationship with a method from the supertype - but
+        * due to covariance there is a mismatch in return values.
+        * Example of when required:
+                Super defines:   Object m(String s)
+                  Sub defines:   String m(String s) 
+                  then we need a bridge method in Sub called 'Object m(String s)' that forwards to 'String m(String s)'
+        */
+       private void createAnyBridgeMethodsForCovariance(BcelClassWeaver weaver, NewMethodTypeMunger munger, ResolvedMember unMangledInterMethod, ResolvedType onType, LazyClassGen gen, Type[] paramTypes) {
+               // PERFORMANCE BOTTLENECK? Might need investigating, method analysis between types in a hierarchy just seems expensive...
+               // COVARIANCE BRIDGING
+               // Algorithm:  Step1. Check in this type - has someone already created the bridge method?
+               //             Step2. Look above us - do we 'override' a method and yet differ in return type (i.e. covariance)
+               //             Step3. Create a forwarding bridge method
+               ResolvedType superclass = onType.getSuperclass();
+               boolean quitRightNow = false;
+               
+               String localMethodName    = unMangledInterMethod.getName();
+               String localParameterSig  = unMangledInterMethod.getParameterSignature();
+               String localReturnTypeESig = unMangledInterMethod.getReturnType().getErasureSignature(); 
+
+               // Step1
+               boolean alreadyDone = false; // Compiler might have done it
+               ResolvedMember[] localMethods = onType.getDeclaredMethods();
+               for (int i = 0; i < localMethods.length; i++) {
+                       ResolvedMember member = localMethods[i];
+                       if (member.getName().equals(localMethodName)) {
+                               // Check the params
+                               if (member.getParameterSignature().equals(localParameterSig)) alreadyDone = true;
+                       }
+               }
+               
+               // Step2
+               if (!alreadyDone) {
+                       // Use the iterator form of 'getMethods()' so we do as little work as necessary
+                       for (Iterator iter = onType.getSuperclass().getMethods();iter.hasNext() && !quitRightNow;) {
+                               ResolvedMember aMethod = (ResolvedMember) iter.next();
+                               if (aMethod.getName().equals(localMethodName) && aMethod.getParameterSignature().equals(localParameterSig)) {
+                                       // check the return types, if they are different we need a bridging method.
+                                       if (!aMethod.getReturnType().getErasureSignature().equals(localReturnTypeESig)) {
+                                               // Step3
+                                               createBridgeMethod(weaver.getWorld(), munger, unMangledInterMethod, gen, paramTypes, aMethod);
+                                               quitRightNow = true;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void createBridgeMethod(BcelWorld world, NewMethodTypeMunger munger, 
+                       ResolvedMember unMangledInterMethod, LazyClassGen gen, Type[] paramTypes, ResolvedMember aMethod) {
+               InstructionList body;
+               InstructionFactory fact;
+               int pos = 0;
+               
+               LazyMethodGen bridgeMethod = makeMethodGen(gen,aMethod); // The bridge method in this type will have the same signature as the one in the supertype
+               bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040 /*BRIDGE    = 0x00000040*/ );
+               UnresolvedType[] newParams = munger.getSignature().getParameterTypes();
+//      paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
+//     Type[] bridgingToParms = BcelWorld.makeBcelTypes(unMangledInterMethod.getParameterTypes());
+               Type returnType   = BcelWorld.makeBcelType(aMethod.getReturnType());
+               body = bridgeMethod.getBody();
+               fact = gen.getFactory();
+
+               if (!unMangledInterMethod.isStatic()) {
+                  body.append(InstructionFactory.createThis());
+                  pos++;
+               }
+               for (int i = 0, len = paramTypes.length; i < len; i++) {
+                 Type paramType = paramTypes[i];
+                 body.append(InstructionFactory.createLoad(paramType, pos));
+//                            if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(unMangledInterMethod.getParameterTypes()[i].getErasureSignature())) {
+//                              System.err.println("Putting in cast from "+paramType+" to "+bridgingToParms[i]);
+//                              body.append(fact.createCast(paramType,bridgingToParms[i]));
+//                            }
+                 pos+=paramType.getSize();
+               }
+
+               body.append(Utility.createInvoke(fact, world,unMangledInterMethod));
+               body.append(InstructionFactory.createReturn(returnType));
+               gen.addMethodGen(bridgeMethod);
+       }
        
     private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) {
         ResolvedMember introduced = munger.getSignature();