Introducing AS3Commons AOP

ActionScript, AOP, AS3Commons, Flex, Java 11 Comments »

The AS3Commons AOP library offers a core API with functionality to implement Aspect Oriented Programming (AOP) concepts in your application or framework. The library uses standard API terminology so that developers who are already familiar with AOP should feel immediately comfortable.

What is AOP?

For those new to AOP, here is a short explanation of the general idea. (If you are already familiar with AOP concepts, you might want to skip this part and go directly to the examples).

The basic idea behind AOP is that an application can be broken down into functional parts that can be conditionally applied to existing code. A classic example is logging, where debug information about certain methods is written to the console in order to get runtime information about the execution of the code. One approach might be to add log statements at the beginning and the end of the methods that you would like to debug. This is quite a tedious task as you need to manually add code to several places. If you ever wanted to get rid of the log statements, you would have to remove the log statements again. With AOP, you can write the logging code in a separate class and then use that class as an Advice on the class that you want to debug. You can then easily reuse the logging code on other methods of other classes.

Terminology

  • Aspect: the general concept of a cross-cutting concern. Logging, Error Handling, Method Run-Time Monitoring are useful examples.
  • Advice: an extra piece of code that needs to be applied. E.g. writing a log statement to the console.
  • Pointcut: a rule about when an Advice should be applied. For instance: all public methods of a class, all methods starting with "load", all methods that take a String parameter, ...
  • Advisor: the combination of an Advice and a Pointcut. This term is not general AOP vocabulary. It was introduced in the Spring AOP framework and is also used in AS3Commons AOP.
  • Joinpoint: a single point in the execution of the code where Advice is applied because the rule of a Pointcut has been satisfied.

Types of Advice

Advice comes in different forms, depending on what and when you want to intercept. The general types are listed below and can be applied to a Constructor, a Method or an Accessor (Getter/Setter):

  • Before: executes before the invocation
  • After: executes after the invocation
  • After Throwing: executes after the invocation threw an error
  • After Returning: executes after normal invocation (when no error was thrown)
  • Around: combines all of the above

The AS3Commons AOP library contains interfaces for all of these kinds of advice. This makes it fairly easy to implement specific advice. Interceptors can also be created that give the developer more control over the invocation than the basic advice interfaces.

How does this work?

Applying Advice to existing code is done at run-time. For this, we create a typed-proxy (also at run-time) of a class or instance that is basically a decorator (or wrapper) around the original class or object that we created. A client then works with the proxy object instead of the original object, which is completely transparent to the caller. Calls to the proxy object are then redirected to the inner (original) object during which extra logic can be executed.

Note: Creating typed-proxies at run-time is made possible by the AS3Commons-Bytecode library.

Example

Consider the following MessageWriter class, which takes an optional message as a constructor argument and has a method to write the message to the console.

Actionscript:
  1. public class MessageWriter {
  2.  
  3.   private var _message:String;
  4.  
  5.   public function MessageWriter(message:String = "") {
  6.     _message = message;
  7.   }
  8.  
  9.   public function writeMessage():void {
  10.     trace("Message: '" + _message + "'");
  11.   }
  12.  
  13. }

We can now create an advice that writes an extra message to the console whenever the writeMessage() method is called. This type of advice is "method before" advice, for which the IMethodBeforeAdvice interface can be implemented.

Actionscript:
  1. public class MethodTracerAdvice implements IMethodBeforeAdvice {
  2.  
  3.   public function MethodTracer() {
  4.   }
  5.  
  6.   public function beforeMethod(method:Method, args:Array, target:*):void {
  7.     trace("* before '" + method.name + "'");
  8.   }
  9.  
  10. }

We can now create a simple application where a proxy is created for the MessageWriter class and the MethodTracerAdvice is applied.

Actionscript:
  1. var factory:AOPProxyFactory = new AOPProxyFactory();   
  2. factory.target = MessageWriter;
  3. factory.addAdvice(new MethodTracerAdvice());
  4.  
  5. var handler:Function = function(event:OperationEvent):void {
  6.   var messageWriter:MessageWriter = factory.getProxy(["Hello World!"]);
  7.   messageWriter.writeMessage();
  8. };
  9.  
  10. var operation:IOperation = factory.load();
  11. operation.addCompleteListener(handler);

The console output would be as follows:

Actionscript:
  1. * before 'writeMessage'
  2. Message: 'Hello World!'

Notice the following things:

  • The target of the AOPProxyFactory is a class. For now, only classes can be proxied but it will also be possible to proxy existing instances.
  • The MethodTracerAdvice class implements the IMethodBeforeAdvice interface. This allows the framework to know when the advice must be executed, namely before the method invocation.
  • There is an asynchronous step in loading the proxy factory, after which the proxy can be requested. If you want to create proxies for more classes, consider using the AOPBatchProxyFactory instead. Note that even with the AOPProxyFactory, you can get multiple instances of a proxy.
  • You can pass constructor arguments to the proxy factory that will be used when creating the proxy. Although not shown in this example, it is possible to intercept and change the constructor arguments using an IConstructorBeforeAdvice.

Example with Pointcut

The previous example applies the "method before" advice on every method call. If we would add another method to the MessageWriter class, say "writeAnotherMessage", then the advice would also be invoked on that method. To control when this advice is applied, we can specify a Pointcut that will instruct the framework about when to apply the advice.

Here is the modified MessageWriter class and example.

Actionscript:
  1. public class MessageWriter {
  2.  
  3.   private var _message:String;
  4.  
  5.   public function MessageWriter(message:String = "") {
  6.     _message = message;
  7.   }
  8.  
  9.   public function writeMessage():void {
  10.     trace("Message: '" + _message + "'");
  11.   }
  12.  
  13.   public function writeAnotherMessage():void {
  14.     trace("Message: 'Konnichiwa!'");
  15.   }
  16.  
  17. }

Actionscript:
  1. var factory:AOPProxyFactory = new AOPProxyFactory();   
  2. var pointcut:IPointcut = new MethodNameMatchPointcut("writeMessage");
  3. var advice:IAdvice = new MethodTracerAdvice();
  4. factory.addAdvisor(new PointcutAdvisor(pointcut, advice));
  5. factory.target = MessageWriter;
  6.  
  7. var handler:Function = function(event:OperationEvent):void {
  8.   var messageWriter:MessageWriter = factory.getProxy(["Hello World!"]);
  9.   messageWriter.writeMessage();
  10.   messageWriter.writeAnotherMessage();
  11. };
  12.  
  13. var operation:IOperation = factory.load();
  14. operation.addCompleteListener(handler);

The console output would now be as follows:

Actionscript:
  1. * before 'writeMessage'
  2. Message: 'Hello World!'
  3. Message: 'Konnichiwa!'

Notice the following:

  • A Pointcut is defined to specify that advice should only be applied if the method name is "writeMessage"
  • The Advice and Pointcut are defined separately and then combined with a PointcutAdvisor. This allows us to reuse Pointcuts and Advice in other scenarios.

Other Types of Advice

The examples shown above only show IMethodBeforeAdvice, but there are a lot more advice interfaces that you can use. As mentioned earlier you can also intercept after invocation. This is not limited to method invocations, but you can also do this for Constructors, Getter and Setters. (Note that there are still some glitches in the alpha code concerning these types of advice.)

Conclusion

The current code is not production ready, but is certainly worth a look if you are interested in using AOP in your application or framework. We will release a first alpha release in the coming days with some samples and documentation. You can already check out the code at the AS3Commons Google Code site.

It is still early in the development so the API might change a bit before the official 1.0 release. If you have any ideas or comments about certain implementations, we're always eager to hear from you.

Some of the things on the roadmap that should make it into the release:

  • AspectJ expression language for pointcuts
  • Composite Pointcuts
  • Proxying of existing object instances

Looking forward to hearing your thoughts and enjoy coding!


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

Unable to access UserTransaction in DataService

Flex, Java, tips 'n tricks 13 Comments »

Note: Just a short post to save your hair from turning gray (I know mine just did)

If you ever run into a "Unable to access UserTransaction in DataService" error when working with LCDS on Tomcat 5.5.x+, make sure you configured the Java Open Transaction Manager (JOTM) correctly. You can do this by adding the following in a project config file (META_INF/context.xml or a file named [MY_PROJECT].xml in [TOMCAT_HOME]/conf/Catalina/localhost):

XML:
  1. <Context reloadable="true">
  2.   <Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>
  3. </Context>

Now if only the Flex Project Wizard would do this for us...


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

JavaPolis (day two)

Conferences, Flex, Java 1 Comment »

JavaPolisThanks to the free pass I got from Christoph Rooms at Adobe, I made it to the JavaPolis conference in Antwerp today. I visited the event last year and certainly didn't want to miss it this year. There is a strange and attractive atmosphere of collective geeky-ness and it is oh so cool. The fact that there are people here from all over the globe proves that this is an interesting conference for every (Java) developer out there. Just like last year, this event seemed professionally organized. At the entrance, every attendee received a backpack with a shirt, a notepad and a conference magazine. There are several boots from vendors that give you interesting information on their products, reductions and of course tons of swag. There are also free drinks for everyone, dinner at noon and fruits and candies.

I arrived pretty late but just in time for the first session and found Peter Elst there as well. Up was a session on Flex for a full house. I think there were easily 500 people in the room. James Ward and Bruce Eckel (that's right, THE Bruce Eckel) were pair presenting and did an excellent job at it. They thoroughly explained the advantages of using Flex as a presentation tier and showed some sample applications. Later on they walked us through an example on how to connect to JSP pages to fetch data and how to consume the Flickr API. The Java crowd seemed to like it and it gave me a confident feeling that we as a development team are using the right technology (Flex) for the right job (interactive user interfaces). Having Bruce Eckel over to present was probably the best move Adobe could make to convince a Java crowd.

Next session was on JavaFX by Jim Weaver. I hadn't seen it in action before so this was my chance of getting to know it. Unfortunately I was not really impressed. The technology seemed to be ages behind on what we are doing today with Flex for RIA development and I can only imagine hard core Java developers wanting to use this. Of course their is a strong programming language behind it - just like C# is for Silverlight - but the whole thing feels like a desperate attempt to catch up with Adobe in the RIA space. I have the same feeling with Silverlight btw.

Last session was Erich Gamma on Jazz. He talked about how agile development teams are working today and how there still are many pain points in bringing all project information together. This being SCM, bug tracking, project management, iteration plans... Jazz attempts to bundle all this info in a single application that makes it easier to access project information for the whole team.


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 
WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in