Summary: | Incorrect ambiguous binding of parameter(s) error | ||
---|---|---|---|
Product: | [Tools] AspectJ | Reporter: | Ramnivas Laddad <ramnivas> |
Component: | Compiler | Assignee: | aspectj inbox <aspectj-inbox> |
Status: | REOPENED --- | QA Contact: | |
Severity: | normal | ||
Priority: | P3 | CC: | abrahas.23, aclement, kvharish.iitkgp, sebtardif |
Version: | DEVELOPMENT | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | Windows XP | ||
Whiteboard: |
Description
Ramnivas Laddad
2005-12-21 20:13:13 EST
The place to fix this is in BcelWeaver.couldEverMatchSameJoinPoints(Pointcut,Pointcut) but here be dragons... it's very easily to return false from this test in too many cases (ie. you think they could never match the same join points, but there's a case you've forgotten). A careful improvement to this algorithm would reduce the number of time we report ambiguous binding when we strictly didn't need to. Well I was going to look at this ... so I wrote this program:
class CommonEntity {
public void add(CommonEntity ce) {}
public void remove(CommonEntity ce) {}
}
class ManageEntity {
ManageEntity(CommonEntity ce) {
}
}
abstract aspect Y {
abstract pointcut entityAccessor(CommonEntity entity);
before(CommonEntity entity): entityAccessor(entity) {}
}
aspect X extends Y {
public pointcut entityAccessor1(CommonEntity entity)
: (execution(* CommonEntity+.add*(CommonEntity+))
|| (execution(* CommonEntity+.remove*(CommonEntity+))))
&& within(CommonEntity+)
&& args(entity) && if(entity != null);
public pointcut entityAccessor2(CommonEntity entity)
: execution(ManageEntity.new(CommonEntity+, ..))
&& within(ManageEntity)
&& args(entity, ..)
&& if(entity != null);
public pointcut entityAccessor(CommonEntity entity)
: entityAccessor1(entity) || entityAccessor2(entity);
}
it only fails at AspectJ 1.5.0:
Complex.java:36 [error] ambiguous binding of parameter(s) entity across '||' in pointcut
: entityAccessor1(entity) || entityAccessor2(entity);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
at either AspectJ 1.5.1a or AspectJ1.5.2 - it compiles fine (who knows what accidentally fixed it... possibly the fixes in pointcut rewriting...)
>ajc Complex.java -showWeaveInfo
Join point 'constructor-execution(void ManageEntity.<init>(CommonEntity))' in Type 'ManageEntity' (Complex.java:10) advised by before advice from 'X' (Complex.java:17) [with runtime test]
Join point 'method-execution(void CommonEntity.add(CommonEntity))' in Type 'CommonEntity' (Complex.java:3) advised by before advice from 'X' (Complex.java:17) [with runtime test]
Join point 'method-execution(void CommonEntity.remove(CommonEntity))' in Type 'CommonEntity' (Complex.java:4) advised by before advice from 'X' (Complex.java:17) [with runtime test]
please reopen if you still have similar problems Ramnivas
not sure what on earth is going on now ... this is one of those cases where when run as a set of tests (Ajc153Tests) it fails, when run standalone it works... so reopening this for now until we get to the bottom of the wierdness. is this still misbehaving? (In reply to comment #4) > is this still misbehaving? > Looks like it is still misbehaving, per http://www.nabble.com/Re:-Match-all-method-calls-with-a-specific-parameter--type-at-any-position-p24222906.html I believe this may be a case of recording the problem against something other than the current unit being processed - that is why it doesn't always get correctly reported and appears to come and go. Any updates on this bug? I am still facing this issue in eclipse indigo using aspectj I'd recommend splitting up your pointcut into pieces to workaround it. Splitting up pointcut is still not working when I use a single advice and have something like (pointcut1(m) || pointcut2(m)) So only option I had is use to use two different advices altogether and have both the advices call another common method. Would appreciate if anyone can provide a workaround using single advice only unsetting the target field which is currently set for something already released I've found that it is still actual for version 1.7.4. Sample code is: public privileged aspect TestAspect { pointcut checkMethodBecauseOfClass(TestAnn access): execution(* *(..)) && @within(access) && if(in(access, ElementType.METHOD)); pointcut checkMethod(TestAnn access): execution(@TestAnn * *.*(..)) && @annotation(access); before(@NotNull TestAnn ann): checkMethodBecauseOfClass(ann) || checkMethod(ann) { final boolean needStack = ann.stackTrace(); logMethod(thisJoinPoint, needStack); } ...... } And the compiller's error is: ajc: ambiguous binding of parameter(s) ann across '||' in pointcut Trying to workaround the issues I tried something like: (cflow(update(session1)) || cflow(delete(session2))) Then in the advice body I just do: Session session = ObjectUtils.firstNonNull(session1,session2); However, AspectJ is still complaining with "Inconsistent binding". At the end of the day, the developer knows better, how can I tell AspectJ to trust my judgment? |