Saturday, February 23, 2008

Using Aspectj and Java Annotations to Try Again

We are working on a program that interacts with a hardware device using a com port for some months. After implementing many parts of software, we found that the communication channel is not as reliable as we expected, so we decided to add some "Try Again" functionality to our code. You have seen the "Try Again" dialog many times, but have you ever taught of how to implement one?

All you need is to invoke a method, if an exception occurs ask the user "Try Again?" and if the answer is "Yes" reinvoke the method. At first it seems so simple to me but after playing with some of OO design patterns I realized that many lines of code should be modified to implement the functionality in OO, so I decided to play a little AOP.

Here is the solution I found:

The first thing we need is to specify what methods must be tried again, Thanks to Java 5 annotations, this is very easy to tag some methods, so the first thing we need is a TryAgain Java annotation:

 
 

package com.blogspot.zoftware.aspects;

 
 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 
 

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface TryAgain {

int count() default 2;

boolean interactive() default true;

}

 
 

The count parameter specifies how many times the method should be reinvoked and the interactive parameter specifies if the user should be asked to try again or not. The second thing we need is an aspect which reinvokes the annotated methods, there are many AOP implementations in the java world but I like the annotation based aspectj the most, as it is very simple and supports standard java syntax, here is the code for the aspect:

 
 

package com.blogspot.zoftware.aspects;

 
 

import java.lang.reflect.Method;

 
 

import javax.swing.JOptionPane;

 
 

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.reflect.MethodSignature;

 
 

@Aspect

public class TryAgainAspect {

 
 

@Around("call(@TryAgain * *..*(..))")

public Object retry(ProceedingJoinPoint jp) throws Throwable{

Method method = ((MethodSignature)jp.getSignature()).getMethod();

TryAgain annotation = method.getAnnotation(TryAgain.class);

Throwable err = null;

 
 

for (int i = 0; i < annotation.count(); i++) {

try {

return jp.proceed();

} catch (Throwable e) {

err = e;

if(annotation.interactive() && !askRetry(e)) {

break;

}

}

}

 
 

throw err;

}

 
 

private boolean askRetry(Throwable e) {

String msg = "The following error occured:\n" + e + "\nRetry?";

return JOptionPane.showConfirmDialog(null, msg) == JOptionPane.YES_OPTION;

}

}


 

 
 

The retry advice, reinvokes every method which is tagged with @TryAgain annotation if an exception occurs (at most count times), so all you need to use this mechanism is to tag the methods that should be reinvoked on failures. Here is a sample usage:

 
 

package com.blogspot.zoftware.demo;

 
 

import com.blogspot.zoftware.aspects.TryAgain;

 
 

public class Foo {

 
 

@TryAgain(count = 3)

public void oftenFails() {

if(Math.random() < 0.6) {

throw new RuntimeException("Sorry, Failed!");

}

}

 
 

public static void main(String[] args) {

new Foo().oftenFails();

System.out.println("Passed");

}

}


 

 
 

The oftenFails method is the method that should be reinvoked, so I annotated it using @TryAgain. To run the code you need aspectj libraries (download here); you can use either dynamic (load time) or static weaving. To use load time weaving, place the following piece of XML into aop.xml under META-INF folder, then run the Foo class with -javaagent:aspectjweaver.jar command line argument.

 
 

<aspects>

<aspect name="com.blogspot.zoftware.aspects.TryAgainAspect" />

</aspects>


 

The mixture of Annotations and AspectJ is a powerful tool to solve many common software engineering problems.

8 comments:

مجيد said...

Nice post.
It seems that AspectJ has very build in capabilities around Remote Method Invocations and Reflection.

Mohsen said...

Of course AOP is a general solution to many traditional problems, it could be used in remoting and in some cases as a replacement for reflection.

Anonymous said...

Keep up the good work.

Anonymous said...

viagra cheap price iframe buy viagra without prescription viagra lawyers buy viagra online at online viagra viagra canada buy viagra on line viagra strips viagra buy viva viagra women's viagra viagra buy purchase viagra buying viagra in uk

Anonymous said...

Yes indeed, in some moments I can reveal that I approve of with you, but you may be inasmuch as other options.
to the article there is quiet a question as you did in the fall delivery of this request www.google.com/ie?as_q=any dvd converter professional 3.5.7 ?
I noticed the utter you suffer with not used. Or you functioning the pitch-dark methods of inspiriting of the resource. I possess a week and do necheg

Anonymous said...

Predilection casinos? inquire this simple [url=http://www.realcazinoz.com]casino[/url] oversee and accomplish displeasing up online casino games like slots, blackjack, roulette, baccarat and more at www.realcazinoz.com .
you can also interfere with our additional [url=http://freecasinogames2010.webs.com]casino[/url] fly at http://freecasinogames2010.webs.com and conquer permitted bucks !
another late-model [url=http://www.ttittancasino.com]casino spiele[/url] locality is www.ttittancasino.com , as opposed to of german gamblers, signpost up manumitted online casino bonus.

Anonymous said...

It isn't hard at all to start making money online in the undercover world of [URL=http://www.www.blackhatmoneymaker.com]blackhat seo forums[/URL], Don’t feel silly if you don't know what blackhat is. Blackhat marketing uses alternative or not-so-known methods to build an income online.

Anonymous said...

Howdy,

I mostly visits this website[url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips].[/url]You have really contiributed very good info here zoftware.blogspot.com. I am sure due to busy scedules we really do not get time to care about our health. Let me present you with one fact here. Recent Scientific Research indicates that closely 90% of all USA grownups are either obese or overweight[url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips].[/url] So if you're one of these individuals, you're not alone. In fact, most of us need to lose a few pounds once in a while to get sexy and perfect six pack abs. Now next question is how you can achive quick weight loss? You can easily lose with with little effort. If you improve some of your daily diet habbits then, its like piece of cake to quickly lose weight.

About me: I am author of [url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips]Quick weight loss tips[/url]. I am also health expert who can help you lose weight quickly. If you do not want to go under hard training program than you may also try [url=http://www.weightrapidloss.com/acai-berry-for-quick-weight-loss]Acai Berry[/url] or [url=http://www.weightrapidloss.com/colon-cleanse-for-weight-loss]Colon Cleansing[/url] for fast weight loss.