Bug 205907 - Custom pointcuts do not work correctly when used in reference pointcuts
Summary: Custom pointcuts do not work correctly when used in reference pointcuts
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P2 normal with 1 vote (vote)
Target Milestone: 1.6.0 RC1   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-10-10 08:45 EDT by Ramnivas Laddad CLA
Modified: 2008-03-14 14:55 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ramnivas Laddad CLA 2007-10-10 08:45:49 EDT
I encountered this problem while implementing the bean() PCD in Spring 2.5. 
In that context (but not in the regular AspectJ context), this is a pretty serious 
bug that is preventing the use of the bean() PCD in a reference pointcut. Note
that when the same pointcut is used directly with advice (anonymous pointcut),
all goes well.

It seems PatternParser.parseReferencePointcut() called by
parseSinglePointcut()) treats a custom poitncut in a similar way to this(), 
target(), @target() etc. and tries to validate the argument to such pointcut
as a type. For a custom PCD that takes a non-type argument (for example, bean() that takes a name-pattern argument), it can't find a matching type and 
ends up throwing an exception.

I will try to create a standalone test case. Meanwhile, the commented out portion
in org.springframework.aop.aspectj.BeanNamePointcutAtAspectTests illustrates the
problem.
Comment 1 Andrew Clement CLA 2007-10-11 05:12:18 EDT
Ramnivas - are you correctly setting your custom handlers on the pattern parser?  Custom handlers are searched before we treat it as a reference pointcut?

This fails for me:

aspect X {
  pointcut p(): bean(foo*);
  before(): p() {}
}

until I register the bean handler with the pattern parser, something like:

BeanDesignatorHandler b = new BeanDesignatorHandler();
Set s = new HashSet();
s.add(b);
patternParser.setPointcutDesignatorHandlers(s,world);

Then the custom handler is discovered at PatternParser.parseSinglePointcut() and we never make it to parseReferencePointcut()

I'm not sure how to access that spring code (yet ;) - so can't see quite what you are doing.  Perhaps you are setting it but a different pattern parser instance is eventually used?  Let me know and I'll investigate further.
Comment 2 Andrew Clement CLA 2007-12-06 06:49:12 EST
I am now able to debug the scenario.

running testMatchBeanName.  First time into the pointcutparser, we parse:

execution(* set*(..)) && bean(testBean1)

and this goes fine.  Second time in we come in with testBean1SetAge() - as a reference pointcut. This parses ok initially, as a ReferencePointcut.  Then we attempt resolution of it with

pc = pc.resolve(resolutionScope);

leading us to this call in ReferencePointcut.resolveBindings()

ResolvedPointcutDefinition pointcutDef = searchType.findPointcut(name);


After messing about in some overly complex iterator combining logic, we end up in:

getDeclaredPointcuts() being called upon org.springframework.aop.aspectj.BeanNamePointcutAtAspectTests$CounterAspect

Then down in the Java15ReflectionBasedReferenceTypeDelegate.getDeclaredPointcuts method we create a new parser of type InternalUseOnlyPointcutParser - this does not have the bean() extension defined and so we treat bean(foo) as a reference pointcut rather than one of our new pointcuts.


The problem is that the InternalUseOnlyPointcutParser is a million miles away from the parser that had the extension registered.  My temporary fix is to associate registered handlers with the Scope within which the pointcuts are being processed.  If we do this up front and pass the scope all the way through, the secondary pointcut parsers that are created can use the same set of extensions and it works fine (or at least the test doesnt fail for this reason any more...).  I just need to justify to myself that this is a suitable use of scope.

Ramnivas - if you want to try it out (and see if the tests are now failing for valid reasons...) I've uploaded a working weaver to:

http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/dev/aspectjweaver-spring.jar

(Might take a while to appear due to replication)

I'll think about the solution I've implemented whilst on my run...
Comment 3 Ramnivas Laddad CLA 2007-12-06 12:00:31 EST
Tested with aspectjweaver-spring.jar. Indeed, that fixes the problem (now tests fail for valid reasons).
Comment 4 Andrew Clement CLA 2008-03-14 14:55:51 EDT
Testcases and fix committed.  I found a much cleaner way to do it on revisiting the bug - extensions to pointcut parsing are associated with the world in which resolution happens for the pointcut parser instance.  So all pointcut parsers sharing a world share the set of registered extensions.