1

I am new to AOP (using AspectJ / ajc) and have searched / googled the internet high and low searching for an answer to my puzzle. Hopefully, someone here might have it.

As I was given to understand by the documentation, AspectJ is suppose to inject code. From my experience, however, it seems like it is mostly adding code (and simply makes an exchange of method calls).

For example, if I have the method:

private static int foo() {
    System.out.println("Hello world");
    return 1;
}

And I define the following around advice for it (with a dummy random in order to manipulate proceed() vs. some other return value):

pointcut foo() : call(int com.mytest.aspects.HelloWorld.foo(..));
int around() : foo() {
    System.out.println("around()");
    if (System.currentTimeMillis() % 2 == 0)
        return proceed();
    return 0;
}

I get the following after decompiling using jd-gui:

  private static final int foo_aroundBody0()
  {
    return foo();
  }

  public static void main(String[] args)
  {
    foo_aroundBody1$advice(HelloAspect.aspectOf(), null);
  }

  private static final int foo_aroundBody1$advice(HelloAspect ajc$aspectInstance, AroundClosure ajc$aroundClosure)
  {
    System.out.println("around()");
    if (System.currentTimeMillis() % 2L == 0L)
    {
      AroundClosure localAroundClosure = ajc$aroundClosure;return foo_aroundBody0();
    }
    return 0;
  }

  private static int foo()
  {
     System.out.println("Hello world");
     return 1;
  }

If that right? Am I perhaps doing something wrong?

I tried using ajc with my android application, but thanks to some jars and SDKs, I got to the dreaded "too many methods" problem.

I am using call pointcuts for most of the time, however it seems that these extra methods are added for each call, even if done within the same class and method, thus increasing my code size and method count significantly.

Any help understanding if this is correct and how it works will be greatly appreciated!

Ori Lentz
  • 3,668
  • 6
  • 22
  • 28

1 Answers1

2

Your understanding is about correct. If you want to avoid too many methods being created, use execution() pointcuts instead of call() wherever possible, because then only one synthetic method per callee will be created, not per caller. I.e. if one method is called from 25 different places, only one additional method will be created instead of 25.

Furthermore you can avoid overhead by limiting the weaving scope of your aspects to the really needed joinpoints. Most aspects I see weave into way too many places. Also, if before() or after() is sufficient, avoid around().

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Yeah, I kind of figured that was the case. Bummer. Thanks anyways. – Ori Lentz Apr 06 '15 at 12:13
  • Well, what did you expect? My guess still is you need to learn how to wield that tool AspectJ, and you are going to be fine. I am. I have used it for years. You know what they say about a fool with a tool. ;-) I remember when I started with AspectJ, OMG! It is just a learning curve, relax and do not just say "bummer" and regard the tool unfit. Maybe it is its user. – kriegaex Apr 06 '15 at 13:37