JBoss AOP v.s AspectJ 5: Pt 2

Introduction

This is part two in a multi part series that will attempt to compare the two leading AOP implementations, AspectJ 5 and JBoss AOP 1.3.x. In this article, we’ll look at some of the differences in creating aspects using both implementations, as well as look at the different compilation and deployment strategies.

In this series, AspectWerkz was not included since AspectJ 5 is the result of the merger between the AspectJ and the AspectWerkz projects. With that said, AspectJ 5 is the logical upgrade path for AspectWerkz users. The Spring Framework is also left out here for the following reasons:

  • It is not a full-blown AOP implementation
  • It works quite nicely with AspectJ
  • Spring 2.0 will make heavier use of AspectJ 5

Since AspectJ and the Spring Framework are complimentary projects, there is no need to compare the two.

The specific versions mentioned in this article are the latest release available at the time of this writing. These are:

  • JBoss AOP 1.3.4
  • AspectJ 5 1.5.0

In part 1, I looked the IDE plugins for both AOP implementations. In this post, we’ll have a look at the differences in coding an aspect using each framework.

Handy Aspect Library

The foundation of this article stems form my experience developing the same aspects using both AOP frameworks. I’ll be referring to code from the aspects found in the the Handy Aspect Library (which will come in both AspectJ and JBoss AOP versions very soon) as examples and will focus on how these aspects are implemented in JBoss AOP and AspectJ code-style. The Handy Aspects are intended for J2SE applications and have no dependency on J2EE or any particular application server. It should be noted that JBoss AOP can run outside of JBoss AS just fine. AspectJ annotation-style aspects I’ve left out because I have found them to be much more cumbersome than the language-base approach. Also, since I didn’t see the need for it, I won’t be going into AspectJ 5’s aop.xml deployment style either. Please note that this time I’ve explicitly acknowledged its existence :)

Pointcuts

Pointcuts are the heart of any AOP implemention. With a pointcut, you define the join point where the where the aspect will execute on the advised code. JBoss AOP supports pointcuts defined in XML and by using Java 5 annotations. AspectJ, being a language extension and all, supports language-based pointcuts, Java 5 annotation-based pointcuts, as well as pointcuts defined in XML. AspectJ and JBoss differ quite a bit when it comes to the pointcut syntax. At first glance, you might think they look strikingly similar, but be aware that they are very different. Pointcut definition is a very, very vast topic, and it may warrant an additional post on the subject. For now, I’m just covering some of the other programming differences between the two AOP frameworks.

Join Points

JBoss AOP operates much more like an event framework: join points are treated more like an event and your advice is akin to an event listener. While there is no strict interface a JBoss AOP aspect must adhere to, all JBoss AOP aspects must return an Object, have a single parameter which is an instance of Invocation, and must throw Throwable. The Invocation interface is where you’ll be able to reference the different players within the join point. In the JavaBean aspect, we have some advice which is responsible for firing property change events. The body of the method looks like this:

public Object fieldChangeAdvice(FieldInvocation invocation) throws Throwable {
     JavaBean bean = (JavaBean) invocation.getTargetObject();
     Field field = invocation.getField();
     String propertyName = field.getName();
     Object before = field.get(bean);
     Object result = invocation.invokeNext();
     Object after = field.get(bean);
     bean.firePropertyChange(propertyName,before, after);
     return result;
}

Any advice in JBoss AOP must return a type of Object even if the method it’s advising has no return value. This is why we return the result of invocation.invokeNext() (which is the AspectJ equivalent to proceed()). To get at the JavaBean itself, we have to call invocation.getTargetObject() and cast it to a JavaBean. Since we know we’ll be operating on a field, we can narrow the parameter type to use FieldInvocation as opposed to having to down-cast an Invocation.

AspectJ does some things a bit differently; here’s what the around advice body looks like in the AspectJ version:

void around(JavaBean bean) : setters(bean) {
     FieldSignature fieldSig = (FieldSignature) thisJoinPoint.getSignature();
     Field field = fieldSig.getField();
     try {
          Object oldValue = field.get(bean);
          proceed(bean);
          Object newValue = field.get(bean);
          bean.firePropertyChange(field.getName(), oldValue,newValue);
     }
     catch(Exception e) {
          e.printStackTrace();
     }
}

Notice how we didn’t need to cast anthing to a JavaBean? In AspectJ, we can have the pointcut do that for us:

pointcut withinConstructor() : withincode((@Observable *).new(..));

pointcut setters(JavaBean bean): target(bean) && set(* (@Observable *).*)
            && withincode(* @Observable *.set*(..)
            && !withinConstructor() && !set(@Silent *(@Observable *).*);

In this pointcut we define the target as the JavaBean which is caputured as a paremeter in the pointcut. While we could still cast thisJoinPoint.getThis() to a JavaBean, we can use the typed poiontcut parameter so there’s no need for a cast in the advice body.

On the flip side, the JBoss approach can make it a lot easier to get up and running for those most comfortable in Java. For starters, you’re still working with Java and the API is pretty straightforward. Compared to AspectJ’s annotated development style, I tend to find JBoss a bit easier to work with. The AspectJ annotated-style development feels like a hodge-podge of AspectWerks and AspectJ. I have tried to get the JavaBean aspect working with the annotated development style, and while for the most part it works well, I am still having a hell of a type getting the inter-type declaration working on the @Observable annotation. The documentation doesn’t seem to cover this quite well.

Join Point Context

In certain instances, JBoss AOP provides a much easier means of accessing specific information of a join point. The most compelling example of this is with a MethodCalledByMethodInvocation. Suppose you have some utility class with several different methods and you want to capture the following information:

  1. The method called on the UtilityClass
  2. The class calling the method on the UtilityClass
  3. The method of the calling class which called the method on the UtilityClass
  4. The parameters of the method of the calling class which called the method on the UtilityClass

Items 1 and 2 are pretty straight forward to get in both JBoss AOP and AspectJ. It is items 3 and 4 that JBoss AOP makes so easy to find. A pointcut for such an operation might look something like this:

AspectJ

pointcut findCallers(): call(* UtilityClass.*(..)) && withincode(* *.*(..));

JBoss AOP

call(* * UtilityClass->*(..)) && withincode(* *->*(..));

In JBoss AOP, the invocation type would be a MethodCalledByMethodInvocation. By calling MethodCalledByMethodInvocation.getCallingObject(), we get a reference to the object wich called the UtilityClass. The calling method can be retrieved by calling MethodCalledByMethodInvocation.getCalledMethod(). This is an incredibly useful feature, and very easy one to use at that.

In AspectJ, this calling object could also be referenced by thisJoinPoint.getThis(). What is odd about using thisJoinPoint.getThis() is that the return value will differ if you use a call vs. an execution pointcut. With a call pointcut it will return the the object that called the method on the UtilityClass. In an execution pointcut, it would return the UtilityClass. What I have yet to be able to figure out is how to capture the method called on the calling class. The MethodSignature of thisJoinPoint only provides the contextual information of the method executed on the UtilityClass, not that of the caller. There is probably a way to capture this information through a pointcut, but the amount of time I have spent trying to figure that out starts to make JBoss AOP look that much more attractive.

Introductions, Mixins, and Intertype Delcarations

One of the more contreversial features of AOP, is the ability force a class to implement a particular interface along with an implemention of that interface. This pretty much can result in enabling multiple-inheritence in Java. The JavaBean aspect relies heavily on this concept since we’re making any advised class implement the the JavaBean interface. Both JBoss AOP and AspectJ take slightly different approaches in how they implement this.

AspectJ calls this feature an Intertype declaration and it basically enables you to delcare that a given class should implement the specified interface. The syntax is like so:


declare parents : (@Observable *) implements JavaBean;

This line says that any type marked @Observable should implement the JavaBean interface. For simple marker interfaces like Serializable, this is all you’d need to do. However, since the JavaBean interface requires several methods to be implemented, the aspect must now also provide the default implementation. To implement the interface methods, we add the following lines:

public void JavaBean.addPropertyChangeListener(PropertyChangeListener listener) {
     pcs.addPropertyChangeListener(listener);
}

By prefixing the method names with that of the interface, the aspect now provides the full implementation of a JavaBean to the advised classes. So essentially, your aspect now becomes the implementation of that interface.

Accomplishing the same thing using AspectJ’s annotation-style development has been elusive task. One might think something like this might do the trick:


@DeclareParents(value="@Observable *",defaultImpl=JavaBeanImpl.class)
private JavaBean javaBean;

However, the type is never woven into the target class. Since this has been working just peachy with the language-based approach, I haven’t spent a whole lot of time trying to figure out why it doesn’t work. Any pointers would be greatly appreciated.

JBoss AOP makes two distinctions to its version of an Intertype Decalration. When you make a class implement an interface, it is known as an Introduction. To provide the implementaion for the introduced interface, you must provide the Mixin class as well. Making an Introduction with a Mixin class with JBoss AOP can be accomplished by doing the following in xml:



     
          com.damnhandy.aspects.bean.JavaBean
          com.damnhandy.aspects.bean.JavaBean
          new com.damnhandy.aspects.bean.jbossimpl.JavaBeanMixin(this)
     


Or using by using annotations:


@Introduction(typeExpression="class(@com.damnhandy.aspects.bean.Observable)",
              interfaces={ JavaBean.class })
public static Object javaBeanIntroduction;

@Mixin(typeExpression = "class(@com.damnhandy.aspects.bean.Observable)",
       interfaces = { JavaBean.class })
public static JavaBeanImpl createJavaBeanMixin(Object obj) {
     return new JavaBeanMixin(obj);
}

The mixin class must have a single arguement constructor whcih takes a type of Object. The parameter is the object that will recieve the introduced type. In the case of the JavaBean aspect, this will be the class that has been marked with the @Observable annotation.

This a very useful AOP feature and both approaches work just fine. Peronsally, I think the JBoss approach is a bit more clear as to what members are doing what. Either way, they both get the job done.

Build

Compiling aspects with JBoss AOP is a two-step process; you compile your classes first with javac, and then run aopc on the compiled classes to apply your aspects. aopc can also generate a report of all of the aspects that have been applied to your classes. This is a handy feature, but it does come with some caveats. For one, to use this feature, it means you have to run aopc twice; once to compile and a second time to see where the aspects have been applied. When running an aopc report, it appears that the second pass invokes the constructors on the aspects. This became a problem for me as one aspect invoked a java.util.Timer instance from the constructor. When invoked, the timer thread would hang the aopc task. It took hours for me to figure out why aopc was hanging.

The AspectJ compiler, ajc, is a lot more mature than aopc. The compiler operates on sources, byte code, or a combination of the two. If you’re using Ant to build your projects, you can set the build.compiler property to use ajc instead of javac. Granted you loose access to several of ajc’s features, but it’s a great option for those who use aspects in testing, but not in production. When compiling your code, ajc will print out warnings if a given pointcut was not matched. Unlike aopc, ajc doesn’t require a second pass to determine where pointcuts have been applied.

Deployment

While JBoss AOP supports hot-deployment of aspects with JBoss AS, I will not be covering that here. For one I haven’t had the need to use it and hot-deployment of aspects doesn’t really interest me much at present.

AspectJ has the simplest deployment of the two: just compile your code with ajc and put aspectjrt.jar in your classpath and you’re off and running. This is true regardless of weather you’re developing a J2EE application or a Swing application.

JBoss AOP deployment is also a bit more involved. The simplest means of deploying an aspect is to put the jboss-aop.xml in the META-INF folder of the Jar. However, if you choose to use annotated aspects, you need to set the jboss.aop.class.path property to point to the jar in the classpath that contains the annotated aspects. What sucks is that this doesn’t work well with Java Web Start. And while JBoss AOP can be used in standalone Java application, it is not very easy to get JBoss AOP working with another application server such as WebLogic. This is too bad since being able to work seamlessly with other application servers that aren’t JBoss could help JBoss AOP adoption.

As far as dependencies go, AspectJ wins here as well. AspectJ requires that only the tiny, 108k, aspectjrt.ajr be in the classpath. It can be in any classpath be it in WEB-INF/lib, APP-INF/lib, or an application specific classpath. JBoss AOP has a lot more dependencies, totaling almost 2MB in size. In the latest 1.3.4 version, there are some JARs which one can assume are intended for client deployments, as there are smaller JARs available in the distribution which are all suffixed with “-client”. However, there is nothing I can find the documentation regarding these JARs, so it’s not clear how these JARs are meant to be used. But even if these JARs are intended for client deployment, it’s still a hefty load compared to AspectJ.

Conclusion

A lot of folks out there have been dumping the JBoss AOP framework and will make ridiculous blanket statements like “AspectJ is the the de-facto standard, so why bother with JBoss AOP.” Statements like that are completely ignorant and offer little value in making decision on which AOP framework might suite your needs. The JBoss EJB3 implementation utilizes thier AOP framework quite heavily. So as long a JBoss AS remains popular, JBoss AOP will be around for some time. Both frameworks are quite good but both still have their warts and wrinkles.

If you’re looking at AOP and are trying to decide which framework to choose, here are a few pointers that I think might helpful:

Consider AspectJ, if:

  • Your project is a non-J2EE application. While JBoss AOP works grand in stand alone applications, there are much more dependencies to manage. Additionally, the size of the dependcies is quite large: 2.4MB for JBoss AOP and 108k for the AspectJ runtime.
  • The size of the AOP runtime is a big consideration. If you’re deploying a Web Start applictaion over the internet, the size of the ApectJ runtime is very attractive.
  • You require semi-decent development tools. AJDT 1.3 currently performs better, and offers much more productivity tools, than the JBoss IDE 1.5 tools for JBoss AOP. Aslo keep in mind that the JBoss IDE plugin currently does not make use of teh latest JBoss AOP release whereas AJDT 1.3 is making use of AspectJ 5.
  • You’re using a non-JBoss application server such as WebLogic. While it can be done, it took a lot of effort to get JBoss AOP working with WLS. AspectJ integration was much more straight forward.

Consider JBoss AOP, if:

  • You’re already working with the JBoss Application Server. It’s already there and JBoss AS sports some additional features when used as part of the container. There is little or no value in introducing a second AOP framework to an application server that directly supports its own AOP framework.
  • You’re more comfortable with a Java-API as opposed to a new language.
  • You don’t want to have to forever to use any new language features that may make it into a furture Java release.

Currently, I enjoy working with both frameworks and I find each has its place depending on the nature of the project. I started out using JBoss AOP because it had support for Java 5 annontations since it’s initial release in Sepetember of 2004. AspectJ on the other hand, didn’t gain Java 5 support until December 2005 – over a full year after Java 5 had been released. Now that AspectJ 5 is here, with full Java 5 support, there aren’t as many fundamental differences between the two frameworks. With that said, it may not be unreasonalble for the JBoss folks and AspectJ team to begin colabroation on a unified AOP framework. Who knows?

To sum up, deciding on which framework to use is a matter of your comfort level with either approach and what it is that your project requires. Both frameworks should get the job done just fine. Hopefully, this article can help make your decision a little easier.

Be Sociable, Share!
    • max

      Nice article, but to be fair JBoss AOP is not dependent on the JBoss appserver nor J2EE – it can run in J2SE and non-JBoss application servers.

    • max

      Nice article, but to be fair JBoss AOP is not dependent on the JBoss appserver nor J2EE – it can run in J2SE and non-JBoss application servers.

    • http://damnhandy.com/ Ryan

      Thanks for the comment Max, but I never implied that JBoss AOP was dependent on JBoss AS. In fact, the Handy Aspect Library is targeted at J2SE applications rather than J2EE. The JavaBean Aspect was developed as way to make POJOs used by Hibernate, support bound properties without changing the orginal code. So I’m well aware that the JBoss AOP can work outside of the container. I have also made some updates to make that point more clear.

    • http://damnhandy.com Ryan

      Thanks for the comment Max, but I never implied that JBoss AOP was dependent on JBoss AS. In fact, the Handy Aspect Library is targeted at J2SE applications rather than J2EE. The JavaBean Aspect was developed as way to make POJOs used by Hibernate, support bound properties without changing the orginal code. So I’m well aware that the JBoss AOP can work outside of the container. I have also made some updates to make that point more clear.

    • max

      Ok, but then I don’t understand the argument for why aspectj should be preferred when doing non-J2EE or when using non-JBoss app servers.

    • max

      Ok, but then I don’t understand the argument for why aspectj should be preferred when doing non-J2EE or when using non-JBoss app servers.

    • Alex

      There are more than five books and tutorials on AspectJ whilst there are none on JBossAOP.
      Also AspectJ is not governed by an app server roadmap but has it own roadmap based on user needs and feedback on the Eclipse community lists. The pointcut mechanism is far more powerfull f.e. not just limited to annotation matching when it comes to Java 5: autoboxing and generics are also supported.
      Also AspectJ 5 gives choice between plain java syntax and dedicated language, and even supports mixing both. It also guarantess interop when mixing compile time / IDE / and load time weaving. Not sure you can expect the same thing in JBossAOP. Left aside JBossIDE is still not final whilst AspectJ AJDT for Eclipse is in its third generation.
      Your article does not compare the runtime performance (after weaving, once running) and I am sure that ‘d be an interesting topic as well to cover to fully compare the two and not ending up in just a small JBossAOP tutorial as this post.

    • Alex

      There are more than five books and tutorials on AspectJ whilst there are none on JBossAOP.
      Also AspectJ is not governed by an app server roadmap but has it own roadmap based on user needs and feedback on the Eclipse community lists. The pointcut mechanism is far more powerfull f.e. not just limited to annotation matching when it comes to Java 5: autoboxing and generics are also supported.
      Also AspectJ 5 gives choice between plain java syntax and dedicated language, and even supports mixing both. It also guarantess interop when mixing compile time / IDE / and load time weaving. Not sure you can expect the same thing in JBossAOP. Left aside JBossIDE is still not final whilst AspectJ AJDT for Eclipse is in its third generation.
      Your article does not compare the runtime performance (after weaving, once running) and I am sure that ‘d be an interesting topic as well to cover to fully compare the two and not ending up in just a small JBossAOP tutorial as this post.

    • http://damnhandy.com/ Ryan

      There can be 20 books on AspectJ, or JBoss AOP for that matter, and I could care less. They’re generall out of date by the time you get them and are by no means a measue of how good or bad a framework is. To call this post “small JBossAOP tutorial” clearly shows that you did not read the article well. I think I gave equal time to both frameworks a showed how to code parts of the same aspect using each framework. Hell, my HandyAspects project on Java.net currently uses AspectJ and not JBoss AOP! And if you bothered to read part 1 you see that I mentioned that JBoss IDE is not anywhere close to that of AJDT. As for performance, that’s on deck for part 3 or 4. Again, if you really read the “series”, you see that there is more of comparison planned. Either way, I find that there’s plenty of room for both frameworks.

      But on the plus side, at least your comment was a geniune one, as opposed to the 100+ spam posts I’ve been getting lately.

    • http://damnhandy.com Ryan

      There can be 20 books on AspectJ, or JBoss AOP for that matter, and I could care less. They’re generall out of date by the time you get them and are by no means a measue of how good or bad a framework is. To call this post “small JBossAOP tutorial” clearly shows that you did not read the article well. I think I gave equal time to both frameworks a showed how to code parts of the same aspect using each framework. Hell, my HandyAspects project on Java.net currently uses AspectJ and not JBoss AOP! And if you bothered to read part 1 you see that I mentioned that JBoss IDE is not anywhere close to that of AJDT. As for performance, that’s on deck for part 3 or 4. Again, if you really read the “series”, you see that there is more of comparison planned. Either way, I find that there’s plenty of room for both frameworks.

      But on the plus side, at least your comment was a geniune one, as opposed to the 100+ spam posts I’ve been getting lately.

    • fordmat3

      A good comparison, i have just started to learn aspectj; having heard about the redhat jboss aquisition i was wondering how aspectj and jboss compaired. As for AJDTs performance i do believe they are working on improving it in the near future.

    • fordmat3

      A good comparison, i have just started to learn aspectj; having heard about the redhat jboss aquisition i was wondering how aspectj and jboss compaired. As for AJDTs performance i do believe they are working on improving it in the near future.

    • Fábio

      I also don’t understand the argument for why aspectj should be preferred when doing non-J2EE or when using non-JBoss app servers.

    • Fábio

      I also don’t understand the argument for why aspectj should be preferred when doing non-J2EE or when using non-JBoss app servers.

    • http://www.objectfirst.com/blog Gagan

      Informative Article.

      I am just starting with AOP and over past one week i have used both AspectJ and JBoss AOP with Eclipse. AspectJ runs out of memory so very often, especially for any non-trivial pattern. But JBoss AOP have been very stable in my little experience.

      Both are good tools nonetheless, and this may just be a problem of AspectJ plugin and not the framework itself, but this made me switch to JBoss AOP. Anyone else faced similar problems?

    • http://www.objectfirst.com/blog Gagan

      Informative Article.

      I am just starting with AOP and over past one week i have used both AspectJ and JBoss AOP with Eclipse. AspectJ runs out of memory so very often, especially for any non-trivial pattern. But JBoss AOP have been very stable in my little experience.

      Both are good tools nonetheless, and this may just be a problem of AspectJ plugin and not the framework itself, but this made me switch to JBoss AOP. Anyone else faced similar problems?