AspectJ, 0.8b5: Real-world AOP tool simplifies OO development

AspectJ Logo

Aspect-Oriented Programming (AOP) allows global properties of a program to determine how it is compiled into an executable program. Traditional units of modularity in programming languages include objects, functions, modules, and procedures. However, some functions cannot be encapsulated in single modules; instead, their implementations end up scattered across the class hierarchy. AOP programming deals with new units of modularity, called "aspects," that involve more than one functional component, such as synchronization, integrity control, persistency, and interaction. Aspects cannot be neatly separated using traditional units of modularity.

Put another way, code relating to aspects is often expressed as small code fragments tangled and scattered throughout several functional components. Because of the way they cross module boundaries, it is said that aspects "crosscut" the program's hierarchical structure. Aspects encapsulate crosscutting concerns.

AspectJ is a general-purpose AOP extension to Java. It enables the modularization of such crosscutting concerns as system-wide error-checking strategies, design patterns, synchronization policies, resource sharing, distribution concerns, and performance optimizations. An open-source project, AspectJ is the product of years of research at Xerox PARC. The project is partially supported by the Defense Advanced Research Projects Agency (DARPA).

The implications for developers of the emergence of real-world AOP tools is simple: If it works the way it's supposed to, AOP could become a powerful means of coping with the staggering complexity that increasingly characterizes software applications. AOP tools hold the potential for simplifying and all but eliminating some of the most time-consuming, frustrating, and difficult aspects of OO development.

We asked Rich Price, who has been working with AspectJ in the electronic billing and payment toolkit group at CheckFree Corp., to review this early AOP tool.

—John K. Waters
Product Review Editor

[email protected]

3.5 Cups Version Reviewed: AspectJ, 0.8b5

Current Version: AspectJ, 0.8b5
CUP RATING SYSTEM:
5 Outstanding 4 Very Good
3 Acceptable 2 Has Potential 1 Poor

I DISCOVERED AspectJ at OOPSLA '99, while attending a tutorial on AOP given by Cristina Lopes and Gregor Kiczales of Xerox PARC. As I sat through the tutorial, it occurred to me that there were some problems in our software at CheckFree that AspectJ seemed ideally suited to solve, if it indeed worked. Upon my return, I downloaded and installed the tools and had my first primitive aspect compiled and running within minutes. After some experimentation, testing, and discussions with other members of the team, it was decided that the benefits of AspectJ outweighed the risks of committing to a tool that was still in beta. We've been using AspectJ extensively for more than a year now, and it continues to evolve from both a language and tools perspective.

The AspectJ syntax is a little difficult to master, but very powerful. The AspectJ approach to AOP is based on points in the execution of a program called "join points." They are accessed in the language by pointcut declarations. A pointcut consists of one or more join points. You can attach a method-like construct called "advice" to pointcuts. Advice can act before or after a method receives a call, or it can wrap a call. An aspect is a class that contains one or more pointcuts or advice. Similar to methods in Java, pointcuts can be assigned accessibility modifiers and can be declared abstract.

One of the most useful features of AspectJ is its ability to create aspects on existing code without the need for refactoring. Though not always necessary, AspectJ has the ability to break encapsulation, albeit in a controlled fashion. Yet this strength can also be a weakness when abused or misunderstood. One of our first uses for AspectJ was to add tracing to an existing code base. At that time, we had more than 500 classes and some 6,000 methods to trace (even more now). Adding the tracing by hand would have been extremely laborious and error-prone, not to mention that any developer adding new classes and/or methods would have had to remember the convention of adding calls to the trace class.

With AspectJ, a single developer was able to create a robust, modular trace aspect in a fraction of the time it would have taken without it. In addition, if we ever need to modify the trace aspect or modify what is traced, we simply make one change in one place.

Another important feature of the language is its ability to associate an aspect instance with a flow of execution across methods residing in different classes. These classes are often part of different hierarchies that are associated at runtime by the flow of execution. AspectJ lets users associate this flow of execution with an aspect and do meaningful things—such as maintaining state—at various join points.

We used this feature to control synchronization by locking and unlocking resources at certain points in a flow of execution that originated from a given method. Without this mechanism, we would have had many classes sprinkled with lock/unlock calls and try/catch/finally blocks instead of localized behavior in the aspect.

Like classes, aspects can be abstract; it is therefore possible to create reusable aspects, as we did with our synchronization and trace aspects. Aspects can also have regular methods just as classes and sub-aspects can inherit pointcuts and methods.

The language, while powerful, has taken our team some time to learn to use effectively. The documentation does not always do the language justice, as there are many powerful features and syntactic nuances that are either not mentioned or only hinted at. There are two main difficulties: learning to think in terms of crosscutting concerns, and figuring out how to capture those concerns using the AspectJ syntax.

To use the language, AspectJ provides three tools: a compiler (AJC), which is mandatory; AJDE, an optional extension to some common IDEs (JBuilder, EMACS, etc.); and an optional aspect-aware documentation tool that front-ends javadoc (AJDOC). The development environment I use is JBuilder4. Installing AspectJ is very simple. You download the jar files from the Web site and execute them using the -jar option.

The AJC tool is actually a pre-compiler written in Java. It quickly compiles aspects and classes together and produces Java source code that is often described as a "weave." AJC then invokes javac to actually compile the weave into bytecode. If you prefer, you can tell AJC to produce only the weave and then invoke javac or the compiler of your choice manually.

An important limitation of AJC is that you must provide it with all of the source code that will be affected by your aspects. Many times, this is either impossible or impractical and limits what you can apply aspects to. (I understand that this limitation will be addressed in a future release.)

Another weakness of this tool: ambiguous error messages. Although I've seen steady improvement in this area, beginning and even advanced AspectJ users confronted with these messages will find themselves reaching out for support. Fortunately, support for this product is outstanding.

AJDE, the IDE tool, also installs easily. You simply copy the two jar files into the /lib/ext directory of JBuilder. AJDE adds some additional icons to the IDE toolbar and a visual representation of how your aspects interact with various class methods called the Structure View (see Figure 1). Once all of the necessary source code has been added to your project, you must first click on the AJ icon, which activates the AJDE environment. AJDE will look at your project and build a list of all source files if one does not already exist. You can have many of these "list" files in the same project; however, I have used only one.

Screenshot
Figure 1. The Aspect Structure View.

To compile, click the AJC compile icon and pick the list file you want to compile. AJC error messages are displayed similar to the Java compiler's error messages. Click on these, and you will be taken to the aspect source code with the line highlighted.

The AspectJ Structure View, although useful, could be better. For instance, some trace aspects interact with thousands of methods over hundreds of classes. The Structure View simply displays a list of all the affected methods that, for our trace aspect, was much too long to be of use. It would be better if it provided an option to list affected classes and then allowed you to drill down to see the affected methods. Also, there is no mechanism to print the view. For aspects such as our trace aspect, it can take quite a while to render the Structure View. In fact, you incur this overhead even when you click on the tab to view the source of the aspect.

The documentation tool, AJDOC, uses javadoc to produce javadoc-style documentation that is aspect-aware. The version of AJDOC I used for this review has some bugs, which I understand are being fixed. AJDOC is important, because you cannot run javadoc natively against the source tree if it contains aspect source code. As a result, you must either sieve out the aspect source or run with AJDOC. In addition, because we deploy our toolkit with javadoc documentation, we do not want our users to see the aspects documented, as we consider them implementation details. AJDOC needs more options to allow fine-tuning of the output.

We have tested AspectJ extensively and feel confident enough in it that we use it in production. We have never had a bug caused by the compiler-generated code. The tools are still rough around the edges, but we have seen steady improvement in functionality and quality over the past year. Support is excellent. Despite some minor annoyances and limitations, I can't imagine not using AspectJ.

BOTTOM LINE:
As software systems become more complex, common behaviors tend to spread out. AspectJ provides a powerful mechanism for capturing these concerns in a modular way. It can also be a useful tool for learning and experimenting with AOP concepts.

Review in a Nutshell
SYSTEM REQUIREMENTS
  • The compiler requires Java2 to run, but can produce code that runs with JDK 1.1.x.
  • A fast CPU with lots of memory, particularly with large projects, is recommended.
  • AJDE supports JBuilder 3.5, 4, and Emacs.
PRICE
Free download.

PROS:

  • Powerful language extension to Java providing better source code modularity and maintainability that really works.
  • Can add new features to existing code without modification.
  • Simple installation and tools mean users can start experimenting right away.
  • Compiler supports all Java-supported platforms.
  • Overall quality and support are above average, considering the product is not only in beta, but free.
CONS:
  • Documentation needs improvement.
  • Concepts and syntax can be difficult to grasp.
  • Compiler needs access to all source code, which is not always practical.
  • A single change often means rebuilding the entire source tree, though build times are minimal.
  • IDE and documentation tools need refinement.
  • Language syntax occasionally changes.

WRITERS' CHOICE AWARDS
As regular readers of Java Report know, once a year we call upon the reporters, feature writers, reviewers, and columnists whose bylines have appeared in our magazine during the year to cast their votes for their favorite Java tools and technologies. All our voters are independent, seasoned Java pros, from in-the-trenches coders to big-picture architects. Last year's list included more than 1,100 products.

Chances are that most Java-based tools and technologies are on our list, but product champions and suppliers can ensure inclusion by sending the following information to Products Editor John K. Waters:

  1. Product name and version
  2. Category (see list)
  3. Brief description (100 words or less)—no PR hyperbole, please!
  4. Contact phone number and e-mail
  5. Company Web site URL

Please send the information to [email protected]. Receipt of the information will be confirmed via e-mail. The winners will be announced in the December issue of Java Report and at the SIGS Conference for Java Development on Oct. 29 in San Jose, CA.

Tentative product categories are as follows:

  • Application Server
  • Bean or Component
  • Class Library
  • Database Product
  • Deployment Tool
  • Embedded Development Tool
  • Graphics & Charting
  • Integrated Development Environment
  • Messaging Tool
  • Middleware
  • Mobile Development Tool
  • Modeling Tool
  • Optimization Tool
  • Performance Profiler
  • Reporting Tool
  • Security Tool
  • Testing Tool
  • Virtual Machine