Bug 250493 - [generics] [itds] AspectJ does not add proper access flag to bridge methods
Summary: [generics] [itds] AspectJ does not add proper access flag to bridge methods
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: 1.6.3   Edit
Assignee: AJDT-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-10 16:59 EDT by Dave Whittaker CLA
Modified: 2008-10-15 16:01 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Whittaker CLA 2008-10-10 16:59:18 EDT
Build ID: M20080911-1700

Steps To Reproduce:
1. Create an ITD containing a method that returns a generic type
2. Add the advised interface to a class
3. Use javassist to check for the BRIDGE access flag on the created bridge method

More information:
I came across this when a library I am using used javassist to do bytecode manipulation of an ITD advised class.  The methods in javassist that result in an error are below.  Honestly, I'm a bit over my head here with where this access flag comes from, but it seems like while the java compiler adds it, the AspectJ compiler does not and that causes javassist to fail with a DuplicateMethodException.

private static boolean isDuplicated(MethodInfo newMethod, String newName,
                                        String newDesc, MethodInfo minfo,
                                        ListIterator it)
    {
        if (!minfo.getName().equals(newName))
            return false;

        String desc = minfo.getDescriptor();
        if (!Descriptor.eqParamTypes(desc, newDesc))
           return false;

        if (desc.equals(newDesc)) {
            if (notBridgeMethod(minfo))
                return true;
            else {
                it.remove();
                return false;
            }
        }
        else
           return notBridgeMethod(minfo) && notBridgeMethod(newMethod);
    }



    /* For a bridge method, see Sec. 15.12.4.5 of JLS 3rd Ed.
     */
    private static boolean notBridgeMethod(MethodInfo minfo) {
        return (minfo.getAccessFlags() & AccessFlag.BRIDGE) == 0;
    }
Comment 1 Andrew Clement CLA 2008-10-14 15:04:30 EDT
test case created:

import java.lang.reflect.Method;
import java.util.*;

interface Super<T> {
	public T getterA();
}

public class Bridged implements Super<String> {
	public String getterA() {
		return "";
	}

	// Print BRIDGE status of all getter* methods
	public static void main(String[] argv) {
		Method[] ms = Bridged.class.getMethods();
		List results = new ArrayList(); 
		for (int i = 0; i < ms.length; i++) {
			if (ms[i].getName().startsWith("getter")) {
				results.add(ms[i].getName()+"()"+ms[i].getReturnType().getName()+ "  isBridged?"+((ms[i].getModifiers() & 0x0040) != 0));
			}
		}
		Collections.sort(results);
		for (Iterator iterator = results.iterator(); iterator.hasNext();) {
			String entry = (String) iterator.next();
			System.out.println(entry);
		}
	}
}

aspect X {
  public T Super<T>.getterB() { return null; }
}

---
Only when generic ITDs are used is the bridge method created without the BRIDGE (0x0040) flag set.  Test and fix committed.  First fix for 1.6.3 !
Comment 2 Dave Whittaker CLA 2008-10-15 15:50:26 EDT
Cool.  Does that mean the fix won't be available through the update site for a while though?
Comment 3 Andrew Clement CLA 2008-10-15 16:01:24 EDT
i am about to put a new AspectJ into AJDT (the first dev build of AspectJ 1.6.3) - so it will be in AJDT within 24hours hopefully.