Skip to end of metadata
Go to start of metadata

Author: jboner jboner

Introduction

In the previous tutorial we learned how to write, define, weave in and run an aspect. So if you have not read it yet, please do that first.

We also learned how to write and use before and after advice, which allowed us to define code blocks that does something before and after a specific action is triggered.

In this tutorial we will learn how to make use of one of the most powerful constructs in AOP; the around advice. We will implement a little around advice that hijacks the HelloWorld.greet() to make the traditional greeting a bit more interesting.

The Test Application

Here is the Hello World application for this tutorial.

It is important to notice that the HelloWorld application is changed some to make this tutorial more relevant.
The HelloWorld2.greet() method now returns a greeting message while in the previous tutorial, the HelloWorld.greet() was simply printing out the message directly.

It is a standard Java application and can be compiled with javac -d target HelloWorld2.java.

However this application is indeed a bit boring and we are all pretty tired of it. So let's try to make it a bit more interesting, let's hijack the HelloWorld2.greet() method.

Writing and defining the Aspect

To be able to hijack the greet() method we need to make use of the around advice construct.

The around advice can be seen as being invoked "around" or "instead of" the the actual method invocation (can be any well-defined action, aka join point), "intercepting" the invocation. Basically it allows us to replace the regular code and define our own code that runs instead of the regular code.

But the key point is that we also have the "magic" method proceed() which allows us to proceed with the invocation and trigger the action that we have just replaced.
Follow?

Let's take a look at some code to make less abstract:

In this code we have an advice method called yellifyier, which we define (using annotations) as being an around advice. What this method does is first invoke the original greet() method (which we have intercepted using the yellifyier around advice) using the "magic" method JoinPoint.proceed(). This method returns the result from the original method invocation. In this case the "Hello World!" string. So what we then do is making the Hello World application yell the greeting. (Well don't know if it was that much more fun.)

In the Around annotation we also bind the advice to a specific join point, in this case an anonymous one that picks out the HelloWorld2.greet() method.

For more information about the annotation and XML definition, pointcut patterns etc. see the online documentation.

We also have to provide a tiny XML deployment descriptor (in this example called aop.xml) to tell the AspectWerkz system which Java classes it should treat and load as aspects:

Weaving and running the Aspect

After adding annotations you need to run a special AspectWerkz tool. This is done after compiling your aspect class files, (i.e. after running javac). The tool, known as the AnnotationC compiler, can be invoked as follows, passing in the source directory (.), and the class directory (target):

For AspectWerkz 1.0 final:

More information on the AnnotationC compiler can be found here.

Now we are ready to run the weave in our aspect and run the Hello World application. This is done using the aspectwerkz command line tool:

See the previous Hello World tutorial on the online documentation for details.

This produces the expected output:

and as you can see, the greeting is now yelled out.

Conclusion

The key points we are trying to illustrate here is that:

  1. the HelloWorld2 application is completely oblivious of the fact that it is actually yelling out the greeting
  2. the yellifier advice implementation is generic and can be used to yell out output captured from any method (that does not return void).

However, you might have noticed that the definition (in the aspect annotation) is not generic but coupled to the HelloWorld2 application. We can easily loosen up this strong coupling and make the aspect completely reusable. For more information about that, read the next tutorial.

  • No labels

5 Comments

  1. To compile, method signature of yellifyier needs to declare the thowing of Throwable.

  2. Anonymous

    For AnnotationC compiler to work properly with aspectwerkz-2.0.RC1 I made
    following two changes.
    1> Added ant-1.5.2.jar in classpath.
    2> used -src and -classes from command line

    So, on my windows system AnnotationC command looks something like this

    java -cp %ASPECTWERKZ_HOME%\lib\aspectwerkz-2.0.RC1.jar;%ASPECTWERKZ_HOME%\lib\ant-1.5.2.jar org.codehaus.aspectwerkz.annotation.AnnotationC -src . -classes target

  3. Anonymous

    If classes are not compiled with -g option weaver throws following errors

    WARNING: unable to register advice: Could not access source information for meth
    od testAOP.HelloWorldHijacker.yellifyier(Lorg/codehaus/aspectwerkz/joinpoint/Joi
    nPoint;)Ljava/lang/Object;. Compile aspects with javac -g.
    Hello World!

    Do I need to compile classes with -g option ?

  4. Anonymous

    if instead of annotations can we do it with xml?

    i tried doing it with xml..but the weaving was not done..

    i think there must be some problem with the syntax ....can u look into the matter and reply with the correct xml file.

    This is the file i made..but the results was not correct.
    <aspectwerkz>

    <system id="AspectWerkzExample">

    <package name="testAOP">

    <aspect class="HelloWorldHijacker"/>

    <pointcut name="greetMethod" expression="execution(* testAOP.HelloWorld2.greet(..))"/>

    <advice name="aroundgreeting" type="around" bind-to="greetMethod"/>

    </package>

    </system>

    </aspectwerkz>

    can anyone help me.............piyush

  5. Hi, the correct XML would be

    <aspectwerkz>
        <system id="AspectWerkzExample">
            <package name="testAOP">
                <aspect class="HelloWorldHijacker">
                    <pointcut name="greetMethod" expression="execution(* testAOP.HelloWorld2.greet(..))"/>
                    <advice name="yellyfier" type="around" bind-to="greetMethod"/>
                </aspect>
            </package>
        </system>
    </aspectwerkz>

    The advice name must match the method in the aspect clas