2016-12-13 8 views
1

У меня есть pointcut, который я пытаюсь использовать с LTW. У меня есть два метода, которые я пытаюсь посоветовать, каждый из которых имеет другой список параметров. Однако у них обоих есть один общий параметр, который я хочу.AspectJ pointcut matching arguments (args()) не подходит правильно

Эти сигнатуры методов я хочу посоветовать:

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) 

Я попытался следующие с пересечениями/совет, но он терпит неудачу; переменная имени пользователя иногда получает инъекционный IP-адрес (т. е. args() из первого 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); 
} 

я ожидал бы, что параметр args() связан со способом исполнения(), но иногда это может показаться, что это «путать», и дает мне IP вместо имени пользователя.

Я неправильно использую AspectJ, или это ошибка в LTW? Я бегу AspectJ 1.6.13

+0

Как подтвердил Энди Клемент в списке рассылки userj-user, это ошибка в AJ complier/weaver. Об ошибке сообщается на странице https://bugs.eclipse.org/bugs/show_bug.cgi?id=509235, чтобы узнать о проблеме. –

+0

В качестве побочного примечания: готовы ли вы перейти на AspectJ 1.8.x? Наверное, Энди не собирается задерживать исправление устаревшей версии 1.6.х. Я действительно удивляюсь, почему вы используете 1.6.13. Есть ли причины, побуждающие вас сделать это? – kriegaex

+0

@kriegaex Мне не удалось получить aspectj 1.8, работающий на моем контейнере jb4 с LTW. –

ответ

1

AspectJ 1.8.9 имеет такое же поведение. Одним из решений/обходных путей для этого было бы разделить совет на два с использованием другого pointcut для каждого случая, а затем делегировать логику, которую вы хотите сделать с именем пользователя, чтобы избежать дублирования кода. Это будет выглядеть примерно так:

@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); 
} 

Я всегда расщепленные советы, основанные на OR-е изд срезов в с использованием привязок, как, что для каждого сценария использования (то есть Pointcut выражения первоначально в сочетании с ||), потому что с @annotation() типа срезов в это приводит к в сообщении об ошибке около непоследовательное связывание. См. Мои два других ответа об этих случаях и аналогичное решение для извлечения общей функциональности по отдельному методу: answer 1, answer 2.

Я считаю, что AspectJ должен проявлять такое же поведение в вашем случае, как и с @annotation() типами pointcuts, поэтому я думаю, что компилятор не сообщает об ошибке и делает неожиданные вещи - это ошибка в самом компиляторе AspectJ.

+1

Я отправил в список aspectj-users, и Энди Клемент подтвердил, что это, вероятно, ошибка в перезаписи pointcut (также с синтаксисом .aj). Я поднял ошибку на https://bugs.eclipse.org/bugs/show_bug.cgi?id=509235. Тем временем, я в конечном итоге сделал то, что вы предложили, но я просто считаю, что это более загроможденный код. –

+0

Благодарим за отправку отчета об ошибке. Я намеревался сделать то же самое, я был слишком занят своими другими задачами. –