Bug 509235 - AspectJ pointcut matching arguments (args()) is not matching correctly
Summary: AspectJ pointcut matching arguments (args()) is not matching correctly
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-14 11:12 EST by Eric B CLA
Modified: 2016-12-14 20:53 EST (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 Eric B CLA 2016-12-14 11:12:03 EST
This issue was initially raised in the aspectj mailing list (http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg15039.html)

I've got an pointcut that I am trying to use with LTW.  I have 2 methods that I am trying to advise, each with a different parameter list.  However, they both have a single common parameter that I want.

These are the method signatures I want to advise:

       public static WorkflowModifierFlags authenticateUser(String username, String password, String ip, boolean webGUI, boolean realAuthentication)
    
       public static boolean loginJAAS(HttpServletRequest request, HttpServletResponse response, String username, String password, HttpSession session)


I've tried the following pointcut/advice, but it is failing; the username variable is sometimes getting injected with the IP address (ie: the args() from the first pointcut).

    @Before("(execution(public static * business.security.service.LoginManagerHelper.authenticateUser(..)) && args( username, ..)) || "
    		+ "(execution(public static * webapp.util.LoginManagerAction.loginJAAS(..)) && args( *, *, username, ..))" )
    public void setUsername(JoinPoint jp, String username) {
    	// inject the username into the MDC
    	MDCUtils.setUsername(username);
    }


I would have expected that the `args()` parameter is associated to the execution() method, but sometimes it would appear that it is "confused", and gives me the IP instead of the username.


From Andy Clement's response:
I was half surprised you didn't get a compiler warning/error that it didn't like your alternatives for binding - to be clear, there is nothing wrong with them theoretically, but I thought the compiler would say it doesn't support doing that. But I just crafted a small similar program and it does what you describe. So definitely an issue - it should either work or you get told it isn't supported. But it shouldn't silently do the wrong thing.  My test program:

---
public class Code {
  public static void main(String []argv) {
    foo("fooname",1,2,3);
    bar("barone","bartwo","barname",1,2,3);
  }

  public static void foo(String username, int i, int j, int k) {}

  public static void bar(String a, String b, String username, int i, int j, int k) { }
}

aspect X {
  before(String username): (execution(public static * foo(..)) && args(username,..)) ||
                           (execution(public static * bar(..)) && args(*,*,username,..)) {
    System.out.println("username = "+username);
  }
}
---

prints

username = fooname
username = barone

I'm suspecting the pointcut validation and rewriting that goes on. 


A post on StackOverflow (http://stackoverflow.com/q/41129938/827480) has confirmed that this is a problem in 1.8.9 as well.
Comment 1 Andrew Clement CLA 2016-12-14 18:05:38 EST
Not the rewriting. More simply because the args(username,..) matches both execution joinpoints (due to the ellipsis). Have to decide if it is worth making it work or for now just improving the validator logic to print out a compiler limitation message for it.
Comment 2 Eric B CLA 2016-12-14 20:53:21 EST
I would have expected that given the logical "AND" and operator precedence rules that the args() would only match the execution joinpoint to which it is associated.  I guess that's where the bug status comes in.