Bug 104229 - Pointcut does not find joinpoint from within anonmous class
Summary: Pointcut does not find joinpoint from within anonmous class
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.0 M4   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-18 11:22 EDT by Eyon Land CLA
Modified: 2005-09-27 08:54 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eyon Land CLA 2005-07-18 11:22:31 EDT
I have an aspect that provides inter-type methods for an interface.  The class
that implements the interface will automatically be provided a default method. 
If an inner class within this class calls this method, my pointcut does not see
the method.  This was working correctly before I switched to source level 5!

Create an interface like...
public interface GoalSelectedNotice {
	  public void goalSelected(Object goal);
}

Within my aspect I have...
    @Retention(RetentionPolicy.RUNTIME) 
    @interface DefaultImplementation {}

	/**
	 * Watch for goalSelected(..) method being called when
	 * not within this aspect.
	 */
	pointcut goalSelectedPointcut(GoalSelectedNotice _this, Object goal): 
		call(void GoalSelectedNotice.goalSelected(Object))
	    && this(_this) && args(goal) && !cflow(adviceexecution());	
	
	after(GoalSelectedNotice _this, Object goal) returning:
	goalSelectedPointcut(_this, goal){
	  System.out.println("OK it worked!");
	}
	/**
	 * Empty body, can be overriden by classes implementing
	 * {@link GoalSelectedNotice}.
	 */
    @DefaultImplementation 
	public void GoalSelectedNotice.goalSelected(Object goal){
	}


I have a JPanel with a JList like...
public class ListPanel extends JPanel implements GoalSelectedNotice{

	private JComboBox jComboBox = null;
	private JList jList = null;
	/**
	 * This is the default constructor
	 */
	public ListPanel() {
		super();
		initialize();
	}
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private  void initialize() {
		this.setLayout(new BorderLayout());
		this.setSize(300,200);
		this.add(getJComboBox(), java.awt.BorderLayout.NORTH);
		this.add(getJList(), java.awt.BorderLayout.CENTER);
	}
	/**
	 * This method initializes jComboBox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */    
	private JComboBox getJComboBox() {
		if (jComboBox == null) {
			jComboBox = new JComboBox(new MyListTypes());
		}
		return jComboBox;
	}
	/**
	 * This method initializes jList	
	 * 	
	 * @return javax.swing.JList	
	 */    
	private JList getJList() {
		if (jList == null) { 
			jList = new JList(new MyListModel());
			jList.addListSelectionListener(
					new  ListSelectionListener(){
						public void valueChanged(ListSelectionEvent e){
							if(!e.getValueIsAdjusting()){
								JList list = (JList)e.getSource();
								Object goal = list.getSelectedValue();
								System.out.println(goal);
// If I replace the line below with...
// ListPanel.this.goalSelected(goal) the join point is not seen!
// This was working before a switched to source level 5!				
				ListPanel.this.sendGoalSelectedNotice((MyGoal)goal); // this is workaround!
							}
						}
					}
					);
		}
		return jList;
	}
	// this is part of workaround
	protected void sendGoalSelectedNotice(MyGoal goal){
                // join point is found by pointcut here!  This is ok!
		goalSelected(goal);
	}
}
Comment 1 Matt Chapman CLA 2005-07-18 11:31:19 EDT
Passing over to the compiler
Comment 2 Adrian Colyer CLA 2005-08-26 11:38:24 EDT
this *may* have been fixed by the recent work we did on anonymous types. need to
verify and fix (if still broken) in M4
Comment 3 Adrian Colyer CLA 2005-09-27 08:54:48 EDT
This is working correctly in the current AspectJ builds.

Note that there is a bug in your pointcut expression:

pointcut goalSelectedPointcut(GoalSelectedNotice _this, Object goal): 
		call(void GoalSelectedNotice.goalSelected(Object))
	    && this(_this) && args(goal) && !cflow(adviceexecution());	

It matches any call join point where "this" is an instance of GoalSelectedNotice.

At the call join point for:  ListPanel.this.goalSelected(goal)
"this" is the anonymous inner class instance, which is NOT an instanceof
GoalSelectedNotice. The "target" of the call IS an instanceof GoalSelectedNotice
(it's the enclosing instance). 

So 
pointcut goalSelectedPointcut(GoalSelectedNotice _this, Object goal): 
		call(void GoalSelectedNotice.goalSelected(Object))
	    && target(_this) && args(goal) && !cflow(adviceexecution());	

matches the join point in question. Different compilation strategies under 1.4
and 1.5 may have led to "this" appearing to be the "wrong" type under 1.4 maybe. 

I've played around with a number of variations in the test suite, and everything
seems to be checking out ok.