FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Architecture & Design
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
September 01, 2001
The First Aspect-Oriented Compiler

Xerox PARC's AspectJ extension is to Java what C++ is to C.

(Page 1 of 2)

September 2001: The First Aspect-Oriented Compiler

It's not every day, or every year, that you come across something that makes you rethink your entire approach to programming. Mark my words, aspects are going to cause an epochal shift in programming right up there with the object shift of a decade ago. Just as objects did, aspects (and the de rigueur "aspect-oriented programming" and even "aspect orientation") facilitate an important and beneficial approach to system structure. The hype cycle has just begun; the backlash is just as inevitable, but there is no question that within a few years, aspects will be as much a part of the programming lexicon as objects are today.

AspectJ is an extension to the Java language that provides Java with aspects in a manner analogous to the way C++ provides C with objects. The AspectJ compiler can produce either Java bytecodes or Java source code. AspectJ is being built by Xerox PARC by a team led by Gregor Kiczales, principal scientist and manager of Xerox PARC's software design area; it is freely available at www.aspectj.org and is partially supported by DARPA (Defense Advanced Research Projects Agency)—so download it, 'cause you're paying for it anyway.

So what are aspects? According to the Aspect-Oriented Programming Homepage,"Aspect-oriented programming (AOP) is a new programming methodology that enables the modularization of crosscutting concerns." The key word is crosscutting: Aspects allow you to attach behavior throughout your system regardless of function calls (the procedural way to associate two parts of a program) or inheritance (an object-oriented alternative way to associate system components). Like inheritance, to be interesting, an aspect has to involve at least three system components: a caller, a receiver, and another, less obvious, participant. In inheritance, a call (or access to a field) may be handled by an "ancestor" object. In aspect-oriented programming, a call or access can be intercepted by an aspect. The events of a running system where an aspect can attach are called join points, and the behavior of the aspect is called the aspect's advice.

An AspectJ "Hello, World!" Program Running Inside Borland's JBuilder IDE

[click for larger image]

AspectJ integrates into several IDEs, including the Jolt-winning JBuilder (see the July 2001 issue). Integration is simple: Copy a .JAR file into JBuilder's /lib/ext directory. AspectJ installs a menu and toolbar; when you compile an AspectJ program, choose the compilation option from AspectJ instead of the main menu (not surprisingly, the default compiler will complain about the word aspect where it expects a class or interface declaration).

The obvious places where aspects can benefit almost any program include debugging support, logging, security and context management, all of which concern most classes in a system and all of which happen to be of particular interest to Web Service developers.

Another incredibly exciting feature of AspectJ is the use of aspects to facilitate roles in patterns. For instance, an aspect can be declared to "+ implements" a class, attaching both the abstract interface and the implementation to an existing class. This is such a powerful design and implementation capability that it's scary—you could essentially build a class from multiple aspects, each of which reflects one component of the class's overall responsibilities. You could, but should you?

Some will say that there's nothing that can be done with AspectJ that can't be done with Java. That's true, just as nothing can be done with C++ that can't be done with C. The issue with programming languages is rarely whether something is possible—it's whether that thing is facilitated. C facilitates manipulation of data at the level of bits and bytes, Perl facilitates string manipulation, Smalltalk facilitates object orientation, and AspectJ facilitates aspect-oriented programming.

I'm convinced that aspects will be as significant as objects because the capabilities of aspect orientation align well with the needs of today's programmers, even as there's a restlessness about the solution (objects as the be-all and end-all of system structure) that we have at hand. You shouldn't underestimate the power of that restlessness, especially with a group of people as creative yet as reliant on tool support as programmers.

Should you consider using AspectJ for your next project? This is a harder question to answer affirmatively. The problem isn't so much the tool; because AspectJ is translator-based, you won't lose access to underlying facilities. But many, if not most, people moving to object orientation had less-than-stellar experiences if the initial project was complex or under schedule pressure. The move toward developing Web-based services, on the other hand, was less traumatic for programmers, since what changed was not fundamental programming concepts so much as "just" the deployment platform. When you combine a new project with a new programming concept, the temptation to use the concept can be so strong that you end up using it everywhere and for everything, ignoring the strengths and techniques that you've built up over your career.

It's one measure of the uniqueness of aspects that I think the first place you should use them (aside from exploring them in weekend projects) is in maintenance. If I were asked to add a new feature to an existing, complex system, I would definitely consider using aspects—if the customer was willing to withstand the various risks associated with AspectJ (chief of which is that either the AspectJ language or the programming community for it may atrophy). The crosscutting nature of aspects is perfectly suited to fitting new functionality into an existing system with minimal modifications (or even, conceivably, none).

AspectJ is the best tool to help Java programmers investigate an exciting programming concept whose time on the main stage of software development has come. Do yourself a favor—download it today.

How Do Aspects Work?
Adding simple code to any Java program enables object logging or tracing or…

Listing 1. A Trivial Java Program

   package helloaspects;
   public class HelloWorld {
     public static void main(String[] args){
       HelloWorld hw = new HelloWorld();
       hw.saySomething();
     }
     private void saySomething(){
       System.out.println("Hello, World!");
     }
   }
Listing 2. A Trivial Aspect

   package helloaspects;

   aspect Trace {
     pointcut printouts(): receptions(void saySomething());
     before(): printouts() {
       System.out.println("*** Entering printMessage ***");
     }
     after():  printouts() {
       System.out.println("*** Exiting printMessage ***");
     }
   }
Listing 1 shows the classic "Hello, World!" program written in Java. Listing 2 is an equally trivial aspect.

The first line of the Trace aspect declares that the aspect is part of the same "helloaspects" package as the HelloWorld class. The second line declares that what we're specifying is an aspect, not a class or interface (nevertheless, in AspectJ, we would save this file as Trace.java). The third line specifies the join point for a pointcut called printouts()—the join point is on "void saySomething()" method receptions. In other words, the printouts() pointcut will be called whenever a saySomething() method is called, in any local class. Lines 4 and 7 declare advice for the printouts() pointcut-one is called before the method executes and one is called afterward.

 

Taking OO and Procedural Programming to the Next Level
Aspects let you modularize design concerns such as synchronization, error-checking and distribution.

To illustrate the power of aspects a bit, consider Listings 3 and 4:

Listing 3. Despite increasing class and call-structure complexity …

   package helloaspects;
   public class HelloWorld {
     public static void main(String[] args){
       HelloWorld hw = new HelloWorld();
       hw.saySomething();
       hw.callSomething();
     }
     private void saySomething(){
       System.out.println("Hello, World!");
     }
     private void callSomething(){
       System.out.println("Before IT constructor");
       InnerTalker it = new InnerTalker();
       System.out.println("After IT constructor");
   	it.innerMethod();
     }
     class InnerTalker{
       InnerTalker(){
         innerMethod();
       }
       void innerMethod(){
         System.out.println("Visit SDMagazine.com");
       }
     }
   }
Now, the main program makes multiple method calls, including constructing an inner class, whose constructor makes a call within itself.

Our aspect class is hardly changed; instead of matching void saySomething() methods, the "**()" says to attach the pointcut to any method whose parameter list is empty.

Listing 4. … Few changes are needed in the aspect.

   package helloaspects;
   aspect Trace {
     pointcut printouts(): receptions(* *());
     before(): printouts() {
       System.out.println("*** Entering " + thisJoinPoint + 
"***");
     }
     after():  printouts() {
       System.out.println("*** Exiting " + thisJoinPoint +
"***");
     }
   }
Additionally, we've accessed a variable that indicates the current join point; the result is:

*** Entering reception(void helloaspects.HelloWorld.saySomething()) ***
Hello, World!
*** Exitingreception(void helloaspects.HelloWorld .saySomething())***
*** Entering reception(void helloaspects.HelloWorld.callSomething()) ***
Before IT constructor
*** Entering reception(void helloaspects.HelloWorld .InnerTalker.innerMethod()) ***
Visit SDMagazine.com
*** Exiting reception(void helloaspects.HelloWorld.InnerTalker.innerMethod())***
After IT constructor
*** Entering reception(void helloaspects.HelloWorld.InnerTalker.innerMethod()) ***
Visit SDMagazine.com
*** Exiting reception(void helloaspects.HelloWorld.InnerTalker.innerMethod())***
*** Exiting reception(void helloaspects.HelloWorld.callSomething())***

Becoming intrigued? The pointcut attaches itself to different methods and different classes, providing event-oriented callbacks at specified points of interest.

 

Aspect J, version 0.8beta4
Price: Free

Technical Requirements:

Runtime requirement of the JDK 1.1 library plus a 38K .JAR file
Development requires the JDK 1.2

Pros:
  1. Crosscutting object structures is a powerful facility.
  2. It's built on top of Java, allowing use of existing systems and tools.
  3. It integrates with JBuilder, Forte, Emacs and Ant.www.aspectj.org

Cons:
  1. Using it probably requires new design strategies.
  2. There is a lack of documentation and guidance.
  3. It may not catch on, leaving current projects high and dry.

1 | 2 Next Page
RELATED ARTICLES
No Related Articles
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK