1

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.

Am I using AspectJ incorrectly, or is this a bug in the LTW? I'm running AspectJ 1.6.13

Eric B.
  • 23,425
  • 50
  • 169
  • 316
  • As confirmed by Andy Clement in the aspectj-user mailing list, this is a bug in the AJ complier/weaver. A bug has been reported at https://bugs.eclipse.org/bugs/show_bug.cgi?id=509235 to track the issue. – Eric B. Dec 14 '16 at 16:14
  • As a side note: Are you ready to upgrade to AspectJ 1.8.x then? I guess Andy is not going to backport the fix to the outdated 1.6.x version. I do wonder why you use 1.6.13 at all. Are there any reasons forcing you to do this? – kriegaex Dec 28 '16 at 10:29
  • @kriegaex I was unable to get aspectj 1.8 working on my jb4 container with LTW. – Eric B. Dec 28 '16 at 13:24

1 Answers1

3

AspectJ 1.8.9 has the same behavior. One solution/workaround to this would be to split the advice into two using a different pointcut for each case, then delegate the logic you want to do with the username to avoid code duplication. It would look similar to this:

@Before("execution(public static * business.security.service.LoginManagerHelper.authenticateUser(..)) && args( username, ..)")
public void pointcut1(String username) {
    doSomethingWithUsername(username);
}

@Before("execution(public static * webapp.util.LoginManagerAction.loginJAAS(..)) && args( *, *, username, ..)")
public void pointcut2(String username) {
    doSomethingWithUsername(username);
}

private void doSomethingWithUsername(String username) {
    // inject the username into the MDC
    MDCUtils.setUsername(username);
}

I always split advices based on OR-ed pointcuts using bindings like that for each use-case (i.e. the pointcut expressions originally combined with ||) because with @annotation() type pointcuts it results in an error message about inconsistent binding. See my two other answers about those cases and a similar solution to extract the common functionality to a separate method: answer 1, answer 2.

I believe AspectJ should exhibit the same behavior in your case as with @annotation() type pointcuts, so I think the compiler not reporting an error and doing unexpected things is a bug in the AspectJ compiler itself.

Community
  • 1
  • 1
Nándor Előd Fekete
  • 6,988
  • 1
  • 22
  • 47
  • 1
    I posted to the aspectj-users list and Andy Clement confirmed that it is likely a bug in the pointcut rewriting (happens with .aj syntax as well). I've raised a bug at https://bugs.eclipse.org/bugs/show_bug.cgi?id=509235. In the meantime, I ended up doing exactly what you had suggested as well - I just find it to be more cluttered code though. – Eric B. Dec 14 '16 at 16:13
  • Thank you for submitting the bug report. I intended to do the same, I was just way too busy with my other tasks. – Nándor Előd Fekete Dec 14 '16 at 16:24