I have captured my problem in the following sample code. HelloWorld
class is my source which needs to be instrumented by HelloWorldTracer
aspect. My objective is to find all the method calls which are in the control flow of HelloWorld.main()
. But I'm not interested in the method calls related to any types in the package java.lang.* (eg: java.lang.StringBuilder
).
package com.abc;
public class HelloWorld {
public static void main(String args[]) {
StringBuilder str = new StringBuilder();
str.toString();
Sample.testMethod();
}
}
package com.abc;
public class Sample {
public static void testMethod()
{
StringBuilder str = new StringBuilder();
str.toString();
}
}
public aspect HelloWorldTracer {
pointcut helloWorldTracker() :
execution(* com.sybase.HelloWorld.main(..)) && within(com.abc..*) && !within(HelloWorldTracer);
pointcut methodTracker():
cflow(helloWorldTracker())
&& !within(java.lang..*) && !within(HelloWorldTracer);
Object around(): methodTracker()
{
System.out.println("Inside advice..." + thisJoinPointStaticPart.getSignature().toString() );
Object o = proceed();
return o;
}
}
Using the poincuts mentioned above the type StringBuilder
is also getting advised even though !within(java.lang..*)
has been explicitly specified in methodTracker()
pointcut. I also tried !within(java.lang.StringBuilder)
and !execution(String java.langStringBuilder.toString(..))
as well, but in vain. Any help in restricting the types from java.lang..* from getting advised will be appreciated.
I think you should use
execution
instead ofwithin
for this case.methodTracker() captures all calls done from not within java.lang.*
The call to StringBuilder.toString() was done from
Sample.testMethod()
is therefor returned by the pointcut.Nitzan Volman's suggestion is not what you want.
First of all, in your code sample probably you want to change
to
Having fixed that, you will get a lot of warnings because you are trying to advise
initialization()
andpreinitialization()
pointcuts witharound()
which is impossible due to compiler limitations.Then when you change your output line to just
You will see what really happens in your code:
I.e. you are not just intercepting method calls (or did you mean to catch method executions, which is not the same?), but all (well, many) sorts of joinpoints. Try this:
Result:
Just in case you only wanted to intercept executions of (instead of calls to) your own (woven) classes anyway, it is even simpler, because then you do not need to exclude the Java classes:
Result:
As you can see, now even
main(..)
is included.