Trygve
Trygve

Reputation: 33

Annotated AspectJ wormhole pattern

Consider the following basic Foo, Bar and Main classes:

package foo;

public class Foo {

    public String randomHello(String name) {
        byte[] random = Bar.generateRandom();
        return random.length + " random  " + name + " bytes";
    }
}

public class Bar {

    public static byte[] generateRandom(){
        byte[] b = new byte[20];
        new Random().nextBytes(b);
        return b;
    }
}

public class Main {

    public static void main(String[] args) {
        Foo foo = new Foo();
        System.out.println(foo.randomHello("AspectJ"));
    }
}

Running Main prints "20 random AspectJ bytes". I want to replace the implementation of Bar.generateRandom when called from Foo.randomHello. This is achieved with the following aspect:

public aspect FooBarAspect {

    pointcut p_randomHello(String name) :
        execution(public String foo.Foo.randomHello(String)) && args(name);

    pointcut p_generateRandom() :
        call(public byte[] foo.Bar.generateRandom());

    Object around(String name) :
        cflow(p_randomHello(name)) && p_generateRandom() {

        byte[] b = new byte[name.length()];
        new Random().nextBytes(b);
        return b;

    }
}

This works and Main now prints "7 random AspectJ bytes".

How can I express the same aspect using annotations? Here's my attempt:

@Aspect
public class FooBarAnnotatedAspect {

    @Pointcut("execution(public String foo.Foo.randomHello(String)) && args(name)")
    public void p_randomHello(String name){};

    @Pointcut("call(public byte[] foo.Bar.generateRandom())")
    public void p_generateRandom(){};

    @Around("cflow(foo.FooBarAnnotatedAspect.p_randomHello(String)) && " +
            "foo.FooBarAnnotatedAspect.p_generateRandom() && args(name)")
    public Object a_foobar(ProceedingJoinPoint joinPoint, String name) throws Throwable {
        byte[] b = new byte[10];
        new Random().nextBytes(b);
        return b;
    }
}

This does not work, and I'm getting the following compiler warning:

advice defined in foo.FooBarAnnotatedAspect has not been applied [Xlint:adviceDidNotMatch]

I've verified that the p_randomHello and p_generateRandom pointcuts are working independently, when not in combination as shown here.

Upvotes: 0

Views: 218

Answers (1)

Andy Clement
Andy Clement

Reputation: 2560

You seem to have changed your pointcut somewhat when converting it to annotation style, there is no need to do that (i.e. duplicating args() in your p_randomHello() and in the @Around pointcut reference). This works for me in your setup: @Around("cflow(p_randomHello(name)) && p_generateRandom() "

Upvotes: 1

Related Questions