Community
Participate
Working Groups
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); } }
Passing over to the compiler
this *may* have been fixed by the recent work we did on anonymous types. need to verify and fix (if still broken) in M4
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.