Community
Participate
Working Groups
Build Identifier: I was updated to new version of aspectj (1.6.11) from ver 1.6.0. My aspect is looking like: @Aspect public class TaskHistoryAspect { @Pointcut("execution(@xxx.TaskModification * *.*(..))") void modification(ProceedingJoinPoint joinPoint) {} @Around("modification(joinPoint)") public Object aroundModification(ProceedingJoinPoint joinPoint) throws Throwable { Object target = joinPoint.getTarget(); Task task = ...// obtaining from args List<Task> list = ... // obtaining from args; try { Object result = joinPoint.proceed(joinPoint.getArgs()); if (task != null) { logModification(joinPoint, task); } else if (list != null) { logModification(joinPoint, list); } return result; } finally { // do somthing } } private void logModification(JoinPoint joinPoint, Task task) { // log for task } private void logModification(JoinPoint joinPoint, List<Task> tasks) { // log for each task in list } } Part of code was skipped for simplifying. After weaving that aspect (I use LTW) was an error: Caused by: java.lang.VerifyError: (class: xxx/TaskHistoryAspect, method: aroundModification signature: (Lorg/aspectj/lang/ProceedingJoinPoint;)Ljava/lang/Object;) Incompatible argument to function I have saved weaved code for class, it seems like (also simplified): @Around(value="modification(joinPoint)") public Object aroundModification(ProceedingJoinPoint joinPoint) throws Throwable { Task task; List list; ... Object obj; Object result = joinPoint.proceed(joinPoint.getArgs()); if(task != null) ajc$inlineAccessMethod$xxx_TaskHistoryAspect$xxx_TaskHistoryAspect$logModification(this, joinPoint, task); else if(list != null) ajc$inlineAccessMethod$xxx_TaskHistoryAspect$xxx_TaskHistoryAspect$logModification(this, joinPoint, list); obj = result; ... } and only 1 method with name ajc$inlineAccessMethod$xxx_TaskHistoryAspect$xxx_TaskHistoryAspect$logModification with Task argument (for List was not presented): public static void ajc$inlineAccessMethod$xxx_TaskHistoryAspect$xxx_TaskHistoryAspect$logModification(TaskHistoryAspect taskhistoryaspect, JoinPoint joinpoint, Task task) { taskhistoryaspect.logModification(joinpoint, task); } I think, the problem cause is incorrect class transformation when there are overloaded methods. It is only hypothesis.. Reproducible: Always
is there anyway you can complete the sample with something that gets advised and shows the failure when executing? I tried creating something simple but it just worked for me.
Created attachment 196820 [details] Initial aspect class TaskHistoryAspect, initial aspect class
Created attachment 196821 [details] Decompiled woven TaskHistoryAspect I had saved transformed TaskHistoryAspect class (in debug during class loading by TomcatInstrumentalClassloader) and decompiled it later. Decompiled class is in attachement
I have attached initial and woven aspects (in files was changed only package, to xxx). Also I have noticed that there is join point from another aspect (ExceptionsTranslationAspect) in method public TaskAuditService getTaskAuditService(). It is strange... I can provide code for ExceptionsTranslationAspect too if needed.
Created attachment 196822 [details] updated decompiled aspect updated
After changing aspect code to new (see below) all things become well. @Around("modification(joinPoint)") public Object aroundModification(ProceedingJoinPoint joinPoint) throws Throwable { Object target = joinPoint.getTarget(); List<Task> list = new LinkedList<Task>(); if (target instanceof TaskAware) { list.add(((TaskAware) target).getTask()); } else { for (Object arg : joinPoint.getArgs()) { if (arg instanceof Task) { list.add((Task) arg); break; } else if(arg instanceof List) { List tmpLst = new LinkedList((List) arg); if (tmpLst.size() > 0 && tmpLst.get(0) instanceof Task) { list.addAll(tmpLst); break; } } } } pushInfoForTaskList(list); try { Object result = joinPoint.proceed(joinPoint.getArgs()); logModification(joinPoint, list); return result; } finally { popInfoForTaskList(list); } }
ok - the problem here is the two similar methods: private void logModification(JoinPoint joinPoint, Task task) { // log for task } private void logModification(JoinPoint joinPoint, List<Task> tasks) { // log for each task in list } These only differ in terms of parameters. AspectJ attempts to generate an accessor method for calling these from elsewhere (it needs to because they are private). Because the parameters aren't used in the logic that computes the accessors, it generates one accessor for both methods (!). Clearly this accessor can't cope with the two kinds of second parameter (task/list) and so a verify error comes out. Simplest workaround is renaming one of them (call it logModificationWithList for example). I have a prototype of the fix but generating two accessors in this situation is breaking some other tests and I still have to get to the bottom of why that is.