1

I have a CachingAspect which performs some simple caching on properly annotated methods using an around advice. Now, what I want to do is to trace the caching and the around advice in particular.

So far I'm able to intercept method calls within the around advice but not the advice itself. Ultimately, I would want to get the signature of the method the around advice is advising. Is it possible?

Thanks in advance!

casperOne
  • 73,706
  • 19
  • 184
  • 253
janhink
  • 4,943
  • 3
  • 29
  • 37
  • My answer contains `adviceexecution()`, i.e. you can intercept other advice with it, exactly like you asked in the other comment. Have you even tried? Thanks for accepting my answer anyway, but my intention was to really help you. Describe your use case more precisely, then I can update my answer. – kriegaex Jul 05 '14 at 08:01
  • I just re-read your question, the intent seems clearer now. Have you updated it after my answer? Anyway, I can look into it during the weekend maybe. At the moment I am not near a PC, I only have a tablet here. – kriegaex Jul 05 '14 at 08:05
  • I was busy and on the road for more than a week, but now I have updated my answer. Check it out for a possible solution. – kriegaex Jul 16 '14 at 15:21

3 Answers3

1

What do you mean by

[adviceexecution pointcut] is not working for me

For me it works just fine, like so:

public aspect MetaAspect {
    before() : within(DummyAspect) && adviceexecution() {
        System.out.println("MetaAspect: " + thisJoinPointStaticPart.getSignature());
        for (Object arg : thisJoinPoint.getArgs())
            System.out.println("    " + arg);
    }
}

From that point, looking at the signatures printed, you should be able to further refine which advice to pick from DummyAspect if there is more than one and they have different signatures.


Update:

Okay, you have edited your question and stated that what you need to determine is not just adviceexecution() but also the intercepted method's signature. There is no 100% solution for that, but if you make sure your intercepted advice somehow refers to methods of thisJoinPointStaticPart, an instance of JoinPoint.StaticPart will be added to the advice's own signature and can be accessed from your meta aspect. Here is a complete code sample:

Driver application:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        Application application = new Application();
        application.writeProperty("fullName", "John Doe");
        application.readProperty("firstName");
        application.doSomething(11);
    }

    public void writeProperty(String name, String value) {}
    public String readProperty(String name) { return "foo"; }
    public void doSomething(int number) {}
}

Caching aspect:

package de.scrum_master.aspect;

public aspect CachingAspect {
    pointcut readMethods(String propertyName) :
        execution(* *.read*(String)) && args(propertyName);

    before(String propertyName) : readMethods(propertyName) {
        System.out.println(
            "[CachingAspect] Read method called for property '" + propertyName + "'"
        );
    }

    Object around(String propertyName) : readMethods(propertyName) {
        System.out.println(
            "[CachingAspect] Caching property '" + propertyName +
            "' in method " + thisJoinPointStaticPart.getSignature()
        );
        return proceed(propertyName);
    }
}

As you can see, there are two advice in this aspect. The first one does not access any join point members, the second one does. I.e. we will be able to find out the second one's target signature only in our meta aspect.

Meta aspect:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint.StaticPart;

public aspect AdviceInterceptor {
    before() : within(CachingAspect) && adviceexecution() {
        System.out.println("[AdviceInterceptor] Intercepting " + thisJoinPointStaticPart);
        boolean foundSignature = false;
        for (Object arg : thisJoinPoint.getArgs()) {
            if (arg instanceof StaticPart) {
                foundSignature = true;
                StaticPart jpStaticPart = (StaticPart) arg;
                System.out.println("[AdviceInterceptor] Target method = " + jpStaticPart.getSignature());
                break;
            }
        }
        if (!foundSignature)
            System.out.println("[AdviceInterceptor] Target method cannot be determined from advice signature");
    }
}

The meta advice iterates over its parameters in order to find a JoinPoint.StaticPart type parameter. If it finds one, it prints its target signature, otherwise it prints a failure note after the loop.

Sample output:

[AdviceInterceptor] Intercepting adviceexecution(void de.scrum_master.aspect.CachingAspect.before(String))
[AdviceInterceptor] Target method cannot be determined from advice signature
[CachingAspect] Read method called for property 'firstName'
[AdviceInterceptor] Intercepting adviceexecution(Object de.scrum_master.aspect.CachingAspect.around(String, AroundClosure, JoinPoint.StaticPart))
[AdviceInterceptor] Target method = String de.scrum_master.app.Application.readProperty(String)
[CachingAspect] Caching property 'firstName' in method String de.scrum_master.app.Application.readProperty(String)
kriegaex
  • 63,017
  • 15
  • 111
  • 202
1

See adviceexecution() pointcut.

Constantiner
  • 14,231
  • 4
  • 27
  • 34
1

You can use the thisJoinPoint.getSignature() inside the advice to get the method signature like this:

pointcut tolog1() : execution(* Activity+.*(..)) ;
before() : tolog1() {
    String method = thisJoinPoint.getSignature().toShortString();

    Log.d(ATAG, "=========== entering " + method+", parms="+Arrays.toString(thisJoinPoint.getArgs()));
}
anjosc
  • 923
  • 7
  • 13
  • Yes, this is what I'm doing in the `around` advice. But now I want to create another advice to trace the `around` advice itself. How do I do that? – janhink May 19 '11 at 15:31