AspectJ in Action, second edtion published

AspectJ in Action, second edition is just published. You can get sample chapters, source code, and more from the book’s web site. You may especially want to read a real world perspective of AOP.

This book took over 3 years to get from proposal to completion and I am glad to have it published finally. It was a lot of work with updates and re-updates, but I am pleased with the end results.

Now that I have taken the dust off my blog, I plan to blog more steadily.

Posted in Technology | Leave a comment

AOP: Myths and realities live at InfoQ.com

InfoQ.com has published my AOP myths and realities talk recorded at a No Fluff Just Stuff conference.

InfoQ.com founded by Floyd Marinescu and Alexandru Popescu (the ‘mindstorm’) is definitely becoming a great portal for enterprise developers. Besides great contents (increasing every day), InfoQ is also featuring a few innovative ideas (a lot more to come, as I understand from talking to Floyd and Alexandru). I like, for example, how the live presentations are featured with both slides and presenter seen simultaneously. This format, I believe, gives a much better sense of “being there”.

Posted in Technology | 1 Comment

AspectJ in Action in Korean

AspectJ in Action has been translated into Korean. While the Korean translation seems to have happened back in late 2005, only now I could confirm it (thanks to my friend Henry Choi for ensuring that I didn’t get lost in translation).

AspectJ in Action (Korean translation)

Posted in Technology | Comments Off

The Spring Experience 2006 conference program

The Spring Experience 2006 program details are now available. Keith Donald and Jay Zimmerman have been working very hard to put together a great show resulting in a three-day conference packed with over 50 sessions covering a wide range of topics. It is not just learning either; there are a few parties including a beach party (complete with TSE2006 beach towel :-) ).

The Spring Experience 2006

I will be presenting four sessions and will be attending many to learn all the interesting things other speakers have been working on.

Posted in Technology | Comments Off

AOP Madness and Sanity: A Response

Graham Hamilton has blogged about AOP: Madness and Sanity. The central theme of the blog seems to be based on a notion that any language that runs on the Java platform must follow the JLS and it is okay for a J2EE container, but not for aspects, to affect program semantics.

Yes, J2EE has been using AOP all along!

This is a myth. The reality is that J2EE has been helping with certain crosscutting concerns such as transaction management and security in a rigid, pre-defined way. AOP is a much more general approach, which works not only for J2EE-like applications, but also for Swing/SWT UI applications and real-time applications etc. Aspects are useful even along with J2EE containers, where the container falls short in meeting project’s needs, as witnessed by the success of the Spring Framework using AOP to improve on J2EE.

As far as possible we have tried to follow the principle that “what you get is what you see”.

This might have been a reasonable argument before Java 1.3. With the addition of dynamic proxies, this argument now works against Java. If I see a method call to an object, I cannot say anything unless I know the proxies in which the object is wrapped. On the other hand, aspects along with tools, very directly show you that there is an advice being applied there. See screenshots in New AJDT releases ease AOP development for examples of these.

The code-that-you-write is the code-that-gets-executed is a thing of a distant past. There is so much post-compilation byte code modification that there is a competition among byte code engineering tools! With JVMTI in Java 5, there is even a blessed mechanism to modify the code while being fed to the VM. I don’t think this “what you get…” argument is even worth putting forward anymore.

The container can intercept incoming calls and add additional semantics. An example of this approach is the way that Java EE containers can add transactional semantics to EJB components by intercepting incoming calls.

And how does JLS come into the picture here (your next point)? Why are these containers more blessed than others? What is the difference between (the presumed good) additional semantics and (the presumed evil) changed semantics? What if I don’t have a blessed container that meets my needs? For example, what should I do as a poor Swing application developer, who is trying to write a responsive application using multiple threads and end up with a ton of duplicated boilerplate code to route calls to the event dispatcher thread? Would it be so bad if I can write a few aspects that make me more productive immediately or should I wait for some blessed container (or its third version!) to help me?

Some uses of AOP rely on using runtime mechanisms to modify semantics that are specified by the Java Language Specification (JLS). For example, side files might specify that various modifications are to be made to target classes to invoke additional code when various operations are performed. Some uses of AOP allow extra code to be invoked when fields are accessed or when methods are called.

AOP systems have their own semantics and language specifications. For example, AspectJ has semantics of interaction between classes and aspects. One needs to understand those semantics associated with the aspects to understand the overall system behavior. In an AOP system, aspects are a first-class participant, not a “side file” at all.

Understanding a Java-based AOP system only in terms of Java is similar to understanding C++ in terms of C semantics. You can’t make the required leap if you limit yourself to expressing classes in terms of structures and method dispatch in terms of invoking an array of function pointers. Similarly, thinking about AOP in terms of JLS and code modification won’t help in understanding the real value of AOP. Indeed, thinking about Java semantics by considering machine code instructions is similarly not helpful: the additional abstractions provide software engineering benefits. The use of byte code modification or the use of proxies is simply an implementation mechanism for AOP.

This criticism of AOP is similar to how procedural crowd responded to OOP. Sure, OOP did obscure the program flow, but we ended up liking the “obscurity”. See my response to myth Aspects obscure program flow for more thoughts.

The real value of AOP is in directly expressing design intents in programming constructs. If my security requirement is to check permission before any publicly accessible method in a class in banking or its subpackage, AOP allows me to map this requirement directly in an aspect such the following. I can now review the implementation and check its adherence to the requirements. If any requirements change, I can simply modify the aspect.

public aspect BankingSecurity {
    pointcut bankingOperation() : execution(* banking..*.*(..));

    before() : bankingOperation() {
        AccessController.checkPermission();
    }
}

Whether this aspect modifies byte code of the selected methods, or a proxy is created that implements the advice, or a VM takes care of dispatching the advice is a secondary consideration.

The JLS carefully specifies the precise semantics of the Java language.

And so does <An-AOP-system>LS. It is just different than the JLS. Fortunately for the Java community, Sun has been supporting alternative languages for the Java platform.

To take an extreme example, if a developer has written a statement “a = b;” then they should be able to rely on the value of the field “b” being assigned to the field “a”, with no side effects. Some AOP toolkits allow arbitrary extra code to be executed when this statement runs, so that there can be arbitrary extra side effects as part of this assignment or even so that an arbitrary different value may be assigned to “a”.

The join point models of AOP systems are pretty restrictive on what you can advise, based on writing maintainable code. In fact, that is how it stands apart from generic byte code modification tools and metaprogramming. AOP’s disciplined approach prevents developers from writing hard-to-maintain programs (within reason, of course, since a determined individual can always write bad program in any language or system).

So let’s consider the “a=b;” example. First of all, you can advise such a statement only if it represents an exposed join point. So for AspectJ, “a” or “b” must be a field of a class: local variables won’t do. Second, is it so arbitrary if I have a “side effect” of notifying observers of state-modification implemented through an aspect? Or is it so arbitrary if I mark the object holding “a” as dirty? In each of these cases, I can modularize observer and dirty-tracking functionality into an aspect rather than scattering it in all the places that modify the state of an object.

Yikes! Similarly, some uses of AOP permit extra code to be inserted on a method call from one method to another, even when the JLS clearly specifies that that method call will occur directly. This enables arbitrary extra code to be executed, with potentially arbitrary side effects, in situations where a Java developer should expect there will be no side effects.

So it is okay for a container to invoke extra code to implement security and transaction management (which may very well use byte-code modification as an implementation technique), but it is not okay for an aspect to do the same thing? Once again, what gives a container a special status? Not the JLS.

“Yikes” would be a response of a Java programmer unaware of an AOP system being used, but it would be a perfectly normal behavior to, say, an AspectJ developer.

In J2SE 5.0, the concept of annotations was added to the Java language. In many ways, annotations were designed to meet similar goals to AOP. The concept of annotations is that developers may apply special markers to target method, fields, or classes in order to designate that they should be processed specially by tools and/or runtime libraries.

So will it be okay if that “tools and/or runtime libraries” is an AOP compiler (like AspectJ) or an AOP system (like Spring)?

See discussion of myth Annotations obviate AOP for a quick response. There is a lot to be said here about AOP’s use of metadata. See “AOP and metadata: A perfect match”, Part 1 and Part 2.

The use of container based AOP seems to provide a reasonable mechanism for supporting AOP “cross cutting concerns” within Java environments, without breaking developers’ expectations of how Java source code behaves.

Knowing the JLS is not sufficient to understand the behavior of a class in a container. For example, if I see an EJB with security attributes specified in its deployment descriptor, would a Java developer expect its methods to throw an authorization exception? See my more detailed response to myth Application frameworks obviate AOP.

Java has been a great language and platform. However, it is coming to a point where some serious innovation is needed to ensure that it remains the front runner. AOP is one such innovation that exemplifies the capability of the core Java platform. AOP addresses crosscutting concerns without having to wait for someone to provide a framework and learn each framework and its versions anew. However, exploiting AOP subject to a strict adherence to the limited approaches of the past is unhelpful.

Posted in Technology | 8 Comments

AOP: Myths and realities

IBM developerWorks has published my AOP myths and realities article. In this article, I examine the following common myths around AOP and discuss their realities. Do you have or have you heard of other myths? Let me know. Perhaps I can address them in another article:

Update: There is a good discussion of this article at TheServerSide.com.

Posted in Technology | Comments Off

Javapolis Experience

Just came back from the Javapolis conference. It was a busy, exhausting, but most importantly, a fun-filled week. Thanks Stephane Janssen and Frederik Santens for inviting me.

I had a pretty busy schedule: one university session, one conference session, one BOF, and three interviews. It was quite a different experience to present in a movie theater with slides projected on the whole screen. The best parts were after the talks when many attendees came by and declared themselves as “AOP converts”.

Javapolis Picture

For BOF, I was up against King Kong! I wasn’t expecting many to attend the BOF session. To my surprise, some hard core developers preferred intelligent discussion on myths and realities of AOP over some mindless movie! As a result, we had some great conversation.

Javapolis Picture

I had the privilege of pair-programming with Rod Johnson on a transaction management aspect. Spring 2.0′s integration with AspectJ will definitely prove to be a highlight of 2006.

Looking forward to next year’s Javapolis!

Posted in Technology | 3 Comments

Creating humane interfaces using AspectJ

Martin Fowler blogged about “minimal” vs. “humane” interface. A minimal interface provides only the basic methods enabling, but not providing, clients to write convenience methods. A humane interface, on the other hand, considers typical uses of the interface and provides convenience methods as a part of the interface itself. Providing convenience methods through a wrapper (similar to the java.util.Collections class) isn’t as natural as providing them as a part of the interface itself. Further, using a wrapper for accessing minor convenience methods (such as List.first() and List.last(), see below) is difficult to justify given the extra code you need to write.

Martin asks “what’s the basis for deciding what should be added to a humane interface?”. This is a really important question. I have seen fat “humane” interfaces, where many methods had dubious value and only increased the complexity of those interfaces. I believe creating good humane interfaces requires that

  • Use cases form the basis for deciding what should be added to a humane interface. This means each project may need different humane interfaces for the same underlying concept.
  • Convenience methods for each use case (or coherent set of use cases) be contributed by separate humanizing modules. This allows keeping the core interfaces clean, while adapting them to project-specific needs by including appropriate modules.

Languages such as Java make the separation hard to achieve, since a type needs to define everything in one place and interfaces cannot contain method implementations. We can overcome these limitations using AspectJ. Here core interfaces follow the minimalist approach and aspects introduce convenience methods using inter-type declarations.

For example, you can humanize the access to the List interface using an aspect such as follows:

public aspect HumanizeListAccess {
    public E List<E>.first() {
        return size() > 0 ? get(0) : null;
    }

    public E List<E>.last() {
        return size() > 0 ? get(size()-1) : null;
    }
}

The aspect introduces two new methods, along with their implementations, to the List interface. Now you can use the interface as follows:

List<string> tickers = new ArrayList</string><string>();
tickers.add("GOOG");
tickers.add("SUNW");
tickers.add("YHOO");

firstTicker = tickers.first();
latestTicker = tickers.last();

The only problem with the above implementation: it works only if you weave this aspect into rt.jar!

Here is another example of humanizing an interface the AOP way (and does not require weaving into rt.jar). Consider the following Inventory interface:

public interface Inventory {
    public void addItem(Item item, int count);
    public void removeItem(Item item, int count);
    public Collection<item> getItems();
    public int getItemCount(Item item);
}

You can humanize this interface to provide price awareness using an aspect as follows:

public aspect HumanizeInventoryPriceAwareness {
    public Item Inventory.getLeastExpensiveItem() {
        float leastPrice = Float.MAX_VALUE;
        Item leastExpensiveItem = null;
        for(Item item : getItems()) {
            if(item.getPrice() < leastPrice) {
                leastPrice = item.getPrice();
                leastExpensiveItem = item;
            }
        }
        return leastExpensiveItem;
    }

    public Item Inventory.getMostExpensiveItem() {
        ... similar to getLeastExpensiveItem()
    }

    public Collection<Item> Inventory.inRangeItems(float lowPrice, float highPrice) {
        Collection</item><item> inRangeItems = new ArrayList</item><item>();
        for(Item item : getItems()) {
            if((item.getPrice() >= lowPrice)
               || (item.getPrice() < = highPrice)) {
                inRangeItems.add(item);
            }
        }
        return inRangeItems;
    }

    public Collection<Item> Inventory.cheaperThanItems(float price) {
        return inRangeItems(0, price);
    }

    public Collection</item><item> Inventory.expensiveThanItems(float price) {
        return inRangeItems(price, Float.MAX_VALUE);
    }
}

The HumanizeInventoryPriceAwareness aspect uses inter-type declarations introducing new methods, along with their implementations, to the Inventory interfaces. Notice, how cheaperThanItems() and expensiveThanItems() themselves use the convenience methods introduced by the same aspect.

Now you can use the humanized Inventory interface as follows:

Inventory inventory = ...

Item leastExpensive = inventory.getLeastExpensiveItem();

Collection</item><item> itemsForFriends = inventory.inRangeItems(20f, 50f);

Collection</item><item> itemsForSpouse = inventory.expensiveThanItems(400f);

Note that nothing prevents you from including the aspects in the same source file as the interface or even as nested aspects inside the interface. If you do so, you will get compartmentalization instead of full separation.

So far, we relied on static crosscutting alone. We can implement more complex convenience methods when we throw in dynamic crosscutting. Here dynamic crosscutting tracks the required information and static crosscutting exposes it. For example, here we track access to the inventory and expose the last accessed item through a method:

public aspect HumanizeInventoryTracking {
    private Item Inventory.lastAccessedItem;

    public Item Inventory.getLastAccessedItem() {
        return lastAccessedItem;
    }

    after(Inventory inventory, Item item) returning
        : (execution(* Inventory.addItem(Item, ..))
           || execution(* Inventory.removeItem(Item,..)))
           && this(inventory)
           && args(item, ..) {
        inventory.lastAccessedItem = item;
    }
}

You can follow this pattern to implement more interesting methods such as addedSinceItems(Date), mostAccessedItem(), and leastAccessedItem().

Implementing humane interfaces with the help of AOP allows developing and maintaining each module separately. It also allows easy customization of an interface to meet a project’s needs by simply choosing a suitable set of aspects. For example, if price awareness isn’t required in your project simply exclude the HumanizeInventoryPriceAwareness aspect.

Posted in Technology | 7 Comments

An AOP success story from the real world

Ken Pelletier sent me an email narrating his experience in applying AspectJ to fix security vulnerabilities in an existing application. This success story illustrates the power of AOP in the real world. Not only he secured his current application in very short period, but also ensured protection against new unsafe code.

Hello Ramnivas,

You may recall that you and I spoke at the NFJS conference again this year, and you were asking what were the barriers to introducing AspectJ into my current project.

I have some good news to report.

I was recently tasked with doing an assessment of our web tier architecture from a security point of view, with an eye toward shoring up any vulnerabilities in preparation for an upcoming security audit. We will be rolling out an internet-facing web application which was previously intended to be only a proof-of- concept for internal use.

As a consequence, there are several places where we render data to the browser without concern for whether it has been cleansed to protect against scripting exploits. I was able to very quickly exploit the site in several ways. Additionally, we are retrieving data from several partners via web services which is also subject to injection of code which, when rendered to a browser, can cause nasty things to happen.

I determined the scope of work to plug the holes was non-trivial. We would have to change all view-rendering code to escape all illegal markup characters prior to returning responses to the browser agent. This would be a big undertaking, and, when it was done, there would be no protection against new code being introduced that was unsafe, except for a coding standard and a policy to do code reviews.

I decided to look at the problem from an aspect point of view, and within about an hour I delivered an aspect to cover all cases. It was remarkable how, with no change to existing code whatsoever, I was able escape all dangerous markup that was bound for the browser. I used an ant task to weave this into a jar when the webapp’s war is assembled for deployment, so the whole thing is virtually transparent to the development process.

I think this is the camel’s nose under the tent. The solution is so small, so airtight, and so unintrusive that I think it has the whole team rethinking their initial skepticism toward using AspectJ. When measured against the ‘traditional’ solution, it wins on all counts.

So, I thank you for your encouragement and guidance. I’ve been to 4 of your sessions at NFJS conferences over the last 3 years and read your AspectJ book thoroughly. I felt well prepared to make the case for AspectJ and to implement the solution in very short time.

- Ken Pelletier
Chicago, IL

Thank you Ken for sharing your experience.

Posted in Technology | Comments Off

AOP and metadata: A perfect match, Part 2 published

IBM developerWorks just published the second part of my two-part article series “AOP and metadata: A perfect match”. While the first part focused on mechanics involved in using metadata with AOP, the second part focuses on the concept of multidimensional interfaces, best practices in using metadata with AOP, and effect of metadata on AOP adoption.

In the first half of this article, I introduced the basics of the new Java™ metadata facility and explained how and where AOP’s join point model could be most beneficially fortified by metadata annotation. I also gave an overview of existing metadata support in three leading AOP systems: AspectWerkz, AspectJ, and JBoss AOP. I touched on the impact of metadata on an AOP system’s modularity, and concluded with a refactoring example demonstrating the gradual introduction of metadata annotation into an AOP system.

In this second half of the article, I’ll suggest a novel way to look at metadata as a pathway into multidimensional signature space. This approach has a practical application in untangling element signatures and is also conceptually useful for designing annotation types, even for developers who do not practice AOP. I will also focus on the most beneficial use of metadata annotation in aspect-oriented programming. Among other things, I will demonstrate an effective use of AOP to reduce the loss of modularity that is sometimes associated with metadata annotation. I’ll conclude the article with a set of guidelines for determining when and how best to use metadata. I’ll also consider the effects of adding a metadata facility on the adoption of AOP.

Posted in Technology | Comments Off

AOP and metadata: A perfect match, Part 1 published

IBM developerWorks has published the first part of my two-part article series “AOP and metadata: A perfect match”. This article is the third in the year-long AOP@Work series. In the first two articles in this series, Mik Kersten presented a thorough comparison of various AOP tools (part1, part2). In my articles, I examine the concepts and mechanics in using metadata with AOP.

The new Java metadata facility, a part of J2SE 5.0, is perhaps the most significant addition to the Java language to date. By providing a standard way to attach additional data to program elements, the metadata facility has the potential to simplify and improve many areas of application development, including configuration management, framework implementation, and code generation. The facility will also have a particularly significant impact on aspect-oriented programming, or AOP.

The combination of metadata and AOP raises important questions, including:

  • What is the impact of the metadata facility on AOP?
  • Is metadata-fortified AOP optional, or is it necessary?
  • What are the guidelines for using metadata effectively with AOP?
  • How will this combination affect the adoption of AOP?

I’ll begin to answer these questions in this two-part article, the second in the new AOP@Work series. In this first half of the article I’ll start with a conceptual overview of metadata and the new Java metadata facility. I’ll also explain the difference between supplying metadata and consuming it, and provide some common programming scenarios that invite the use of metadata annotation. Next, I’ll quickly review the basics of AOP’s join point model and explain where it would benefit from metadata fortification. I’ll conclude with a practical example, evolving a design through five stages using metadata-fortified AOP. In Part 2, I’ll demonstrate a novel way to view metadata as a signature in a multidimensional concern space, talk about the impact of metadata on AOP adoption, and conclude with some guidelines for effectively combining AOP and metadata.

Posted in Technology | Comments Off

Metadata for language extensions

My two-part article series “AOP and metadata: A perfect match[Update: Link added, since the article is now published], a part of the AOP@Work series, is about to go live on developerWorks. The first part of the series includes a small section on using metadata to extend the underlying language. However, this topic needs a more elaborate discussion, and hence this blog.

The new metadata facility in Java 5.0 can be used to extend the Java language. In this usage model, an annotation processor alters the semantics of program elements marked with special annotations. Such usage of metadata brings interesting possibilities and a few concerns.

The idea of using metadata to extend the language is not new. AOP systems such as AspectWerkz, JBoss AOP, and now the metadata-driven syntax in AspectJ5 (informally called @AspectJ syntax) use this idea to provide aspect-oriented extensions to Java, in which ordinary program elements are reinterpreted as AOP constructs. For example, you can mark a class to function like an aspect, a method as a pointcut or advice, and so on.

Extension classification

We can classify language extensions using metadata into three categories based on how they affect the programs: compile-time extensions, structural modifications, and behavioral modifications.

Compile-time extensions

These extensions make the compiler perform additional tasks but do not affect the compiled code. Java 5.0 already includes examples of this with @Override, @Deprecated and @SuppressWarnings annotations (albeit as a standard feature, rather than an extension).

Generalizing this idea, you can imagine extending the compiler to issue custom errors and warnings upon detecting certain usage patterns. For example, we can use a Const annotation type to implement the functionality of the C++ “const” keyword in Java. Consider the following annotation type:

public @interface Const {
}

Now consider the following class that uses this annotation:

public class ShoppingCart {

    ...

    public void addItem(@Const Item item) {
        // can't directly modify item or call methods that could modify item
    }

    public void removeItem(@Const Item item) {
        // can't directly modify item or call methods that could modify item
    }

    @Const
    public float getTotal() {
        // can't directly modify 'this' or call methods that could modify 'this'
        return 0;
    }
}

The annotation processor would consume the @Const annotations to produce compile-time errors for any attempts to modify an item while adding or removing from a shopping cart or any attempts to modify the state of shopping cart while querying for the total.

Okay, the language extension using @Const is only a theoretical possibility, since I don’t think it will be of much practical value unless the core Java classes and existing libraries adopt this annotation type and its semantics. Nevertheless, it is an interesting theoretical possibility.

Structural modifications

These extensions modify the structure of the program without modifying the behavior. For example, we could use a @Property annotation to mark fields of a class as properties. An annotation processor then processes the annotations to add a getter method and/or a setter method for each property based on whether it is a read-write, read-only, or write-only property. Essentially, with this extension, you get the property feature support similar to the one in Groovy and C#.

Consider the following annotation type and the associated enumeration type:

public @interface Property {
    public PropertyKind value() default PropertyKind.ReadWrite;
}
public enum PropertyKind {
    ReadWrite, ReadOnly, WriteOnly;
}

Now consider the following class:

public class Person {
    @Property(ReadOnly) private long id;
    @Property private String name;
}

The annotation processor would consume the @Property to translate this class into a byte-code equivalent of the following snippet:

public class Person {
    @Property(ReadOnly) private long id;
    @Property private String name;

    public long getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

If a getter or setter already existed for a property, the annotation processor would leave it untouched.

We can use the same idea to support certain structural design patterns directly into the extended language. For example, we can implement the singleton pattern by allowing classes to be marked with an annotation. Consider the following annotation and enumeration types:

public @interface Singleton {
    public SingletonKind value() default SingletonKind.Lazy;
}
public enum SingletonKind {
    Lazy,   // create the singleton instance upon first use
    Eager;  // create the singleton instance as soon as possible
}

Now consider a class marked with a @Singleton annotation:

@Singleton(Lazy)
public class Service {
    public void serve() {
        //...
    }
}

The annotation processor will translate this class into a byte-code equivalent of the following snippet:

@Singleton(Lazy)
public class Service {
    private static Service _instance;

    public static Service instance() {
        if(_instance == null) {
            _instance = new Service();
        }
        return _instance;
    }

    private Service() {
    }

    public void serve() {
        ...
    }
}

The annotation processor could also modify compile-time behavior to flag the presence of unsupportable structures such as non-zero arguments constructors.

Behavior modifications

These extensions alter the program behavior. For example, they may add additional code to implement security feature in all the program elements with a @Secure annotation. EJB 3.0 annotations essentially extend the Java language in the same vein. Another good example of this kind of extension is ContractJ that implements DBC in Java.

While implementing behavior modifications through language extension can be useful in some situations, aspect-oriented programming is a much better way to do the job. When implemented using AOP, the behavior logic doesn’t disappear into code in an annotation processor, the code expressed remains much more readable, and the debugging process remains natural.

Extension implementation

While some of the features described here can be implemented through a pre-processor (generating code) or post processor (modifying byte-code), a more convenient way would be to allow plugins to the compiler. It would not be surprising if a future tool’s JSR proposes a standard way to extend the compiler (perhaps called “complet”, in the same spirit as “doclet” to use with Javadoc). Perhaps the Pluggable Annotation Processing API (JSR 269) might be the one to standardize such a facility.

Impact on Java

This possibility allows incorporating new features in the language without having to wait for them to make it into the standard. However, abusing this possibility can wreak havoc on the comprehensibility of the programs. Using this possibility to create principled extensions will make Java a more expressive language. AOP systems using annotations to add aspect-oriented features to Java is a good example of principled extensions (in that there is a system behind it — aspect-oriented programming). Using this possibility to add ad hoc extensions, on the other hand, will make programs hard to follow without the context of the associated annotation processing.

How the community uses the metadata feature in general, and the language-extension use case in particular, will be interesting to watch.

Posted in Technology | 3 Comments

NFJS 2005 season starts tomorrow

No Fluff Just Stuff symposium 2005 season is starting tomorrow.

I love speaking at NFJS symposiums. These symposiums are very well organized, topics chosen are timely and relevant, attendees are awesome, and the speaker selection is great :-) . The thing I like most about these symposiums is interactions between speakers and attendees. These interactions help me understand different views and address specific questions and concerns. I also like feedback provided by the attendees, which helps me continuously improve my presentations.

This year, my talks will cover topics in aspect-oriented programming, core Java, and J2EE. This will be the most exciting year for AOP. With the merger of AspectJ+AspectWerkz and incorporation of many new features in AspectJ 5 (such as support for metadata-based crosscutting), adopting AOP will be easier than ever before. Through my AOP talks, I hope to convey the real deal behind AOP, show many real world applications of it, and discuss pragmatic paths in adopting it.

One of the perks of being an NFJS speaker is getting to attend other speakers’ talks. There are many new talks this year and I am looking forward to attend them.

Posted in Technology | Comments Off

Making Eclipse snappier with KeepResident

KeepResident is a very effective Eclipse plugin (for Windows) that eliminates mystery slowdowns often experienced by Eclipse users. It makes Eclipse snappy by encouraging the Windows virtual memory manager to keep the JVM process memory in RAM.

Most of my talks include several demos using Eclipse. To save time, I get Eclipse up and running with the right projects opened before going to my talks. However, when I bring up Eclipse from the minimized state, it takes about a minute before running at the full speed (and with so many people watching, a minute feels like an eternity!). Further, during the presentations, Eclipse often becomes irresponsive for a few seconds. With the KeepResident plugin, those delays are virtually gone.

Posted in Technology | 2 Comments

Preferred way of specifying metadata

I share Dion’s concern about metadata hell. I think the key to using annotations correctly is to realize that annotations supply metadata i.e. additional data about the element being annotated. In other words, annotations should describe the element’s characteristics, and not what should happen before/after/around those elements. Here are some examples to illustrate the point.

In the first example, the apparent intention is to show the wait cursor around methods with the @WaitCursor annotation (using annotation processor or AOP etc.):

// Not preferred
@WaitCursor
public void foo() {
}

The problem is that the method is carrying too implementation-specific metadata. A preferred way is to specify the expected time of execution for the method (many fine details omitted; see AspectJ language support for metadata for more detailed examples):

// Preferred
@Timing(avg=50)
public void foo() {
}

An annotation processor or an aspect may use the timing information to show the wait cursor around slow methods. The biggest difference is that the processors and aspects get to decide how to classify methods as slow and what needs to happen for the slow methods. For example, in a non-UI application, it may choose to do nothing. Further, the same information can be used for other purposes: rate monotonic analysis (RMA), connect with a monitoring agent to implement alerts, etc.

As a second example, the apparent intention is to introduce automatic fault tolerance through retries for retry-safe operations:

// Not preferred
@RetryUponFailure
public void getBalance() {
}

A better way is to specify that operation is idempotent and let the annotation processors or aspects decide how to use this additional information:

// Preferred
@Idempotent
public void getBalance() {
}

Finally, here is another example, where the programmer wishes to remove verbose code needed for read-write lock management through the use of annoations.

// Not preferred
@ReadLock
public float getBalance() {
}

@WriteLock
public void credit(float amount) {
}

A better way is to specify if methods are modifying object’s state:

// Preferred
@ReadOperation
public float getBalance() {
}

@WriteOperation
public void credit(float amount) {
}

That said, there are cases where the additional information makes sense only in the context of specific concerns. In those cases, the scenario becomes a little murky. Consider for example, situation where database table names are specified using annotations:

@Persistence(table="myTable")
public class MyClass {
}

The Persistence annotation makes sense only in the context of persistence concern and not when MyClass is considered in isolation. The question to ponder over: Should such metadata be specified in the class itself? The issue with this example is not surprising given debate over the best place to put such annotations — doclet tags or XML mapping document. It will be interesting to watch how the Java community ends up using metadata.

Posted in Technology | 1 Comment

AspectWerkz 2.0 RC1 is released

AspectWerkz team has just released the 2.0 version. The new version contains many good features from the AspectJ users’ perspective :

  • AspectWerkz is now an extensible aspect container. AspectJ excels at providing a language-level support for AOP concepts and AspectWerkz excels at its integration with application servers. It seems that one can now write aspects in AspectJ and deploy using AspectWerkz’s deployment technology.
  • AspectWerkz’s AOP support is now more closely aligned to that implemented in AspectJ:
    • variations of the after() advice
    • percflow() aspect association
    • this(), target(), and args() pointcuts to capture join point context

    The AspectWerkz team plans to address some of the remaining differences from AspectJ (cflow(), cflowbelow() etc.) in a future version. It seems like AspectJ and AspectWerkz will become nearly isomorphic — you can write program in AspectJ or AspectWerkz and translate between them without much loss of information.

Of course, there are many AspectWerkz-specific improvements such as 20x improvement in performance and hot deployment/redeployment that got to make it more useful as an enterprise AOP solution.

This is exciting! Congratulation to the AspectWerkz team.

Posted in Technology | 1 Comment

AspectJ language support for metadata

Metadata and aspect-oriented programming (AOP) is an interesting combination. I am particularly interested in how the metadata facility will impact the AspectJ language. So I gathered all my thoughts in form of a proposal to modify the AspectJ language to support metadata.

At a high level, metadata support in AspectJ requires:

  • Language support for consuming annotations
    • Selecting join points based on annotations associated with program elements
    • Capturing the annotation instances associated with the captured join points using
      1. pointcuts
      2. reflective APIs
  • Language support for supplying annotations
    • Attaching annotations to join points in a crosscutting manner

Language extension to support metadata in AspectJ should be fully backwards compatible and flow well with the current language. This requires following two principles:

  • Introduce no new keywords, if possible.
  • Align with the existing pointcuts and APIs as much as possible.

The proposed syntax can be divided into four parts: extending the signature syntax to allow specifying annotations, adding new pointcuts to allow selecting join points based on annotation associated with them as well as capturing annotation instances as pointcut context, syntax to supply annotations, and modification to reflection APIs to access annotations.

Extending the signature syntax

Adrian Coyler, the AspectJ team lead, has written a design note to extend signature patterns in AspectJ to select join points based on metadata. I have taken Adrian’s idea and extended it to cover more complex cases such as matching based on annotation properties:

Let’s dive directly into a few examples to illustrate the new syntax.

Pointcut Join points matched
execution(@Idempotent public * *.*(..))
Execution of methods that carry an @Idempotent annotation (such as @Idempotent public long getId())
execution(public * *.*(@ReadOnly *, ..))
Execution of methods whose first argument carries a @ReadOnly annotation
set(* @ContainerSupplied dataSource)
Write-access to all fields named dataSource marked with a @ContainerSupplied annotation
within(@Secure *)
All join points inside any type with a @Secure annotation
within(@Secure * && @Persistent *)
All join points within lexical scope of all types that have a @Secure and a @Persistent annotation
 within(@Secure *..*)
All join points within lexical scope of all types that have a direct or indirect parent package with a @Secure annotation
 within(@Secure *.@Sensitive *..*)
All join points within lexical scope of all types that have a direct or indirect parent package with a @Secure annotation whose child package carries a @Sensitive annotation

I think within() with just annotation type as type pattern such as within(@Secure) should be a compile-time error, since it does not make sense to capture anything in the annotation type itself — compiler generated code for property access in annotation types is irrelevant from user perspective.

Next, we need syntax for matching join points based on annotation property values and not just annotation types. Note that while the proposal to capture annotation instances using pointcuts can achieve a similar effect, those pointcuts will probably fall into dynamically determinable pointcut category. Here are a few examples that capture join points based on annotation properties.

The following pointcut matches all methods that carry a @Transactional annotation:

execution(@Transactional *.*(..))

The following pointcut restricts the selection to only methods that have the kind property set to Required:

execution(@Transactional(kind==Required) *.*(..))

The following pointcut restricts the selection to only methods that have the kind property set to either Required or RequiredNew:

execution(@Transactional(kind==Required || kind==RequiredNew) *.*(..))

In short, one may specify any Java boolean expression that uses properties and constants to filter the join point selection. Here is a pointcut indicative of complex pointcuts one may write :-) :

pointcut longRunningTransactionalRequiredOps()
    : execution(@Transactional(kind==Required || kind==RequiredNew)
                @Timing((min > 30 || max > 100 || ((max-min) > 50))
                        || (avg > 40 && variance > 0.35)) *.*(..))

For wildcard treatment, annotation types should be considered just like other types. Note that since the Java language does not permit inheritance with annotation types, the ‘+’ wildcard won’t make sense (I think it should be a compile-time error to specify annotation type with the ‘+’ wildcard).

New pointcuts

New proposed pointcuts allow select join points based on annotations as well as capturing annotation instances as pointcut context by extending the current this(), target(), and args() pointcuts.

  • @interface(AnnotationTypeOrIdentifier) to capture annotations attached to the program element corresponding to the captured join points themselves. (Note to those attended/viewed my JavaOne presentation: I used annotation(AnnotationTypeOrIdentifier) in that presentation. After more thought, it seems a good idea to avoid a new keyword. While annotation() seems clearer, once Java developers get used to defining annotation types using @interface syntax, the @interface() pointcut may feel more natural.)
  • @this(AnnotationTypeOrIdentifier) to capture annotations attached to the this object associated with the captured join point.
  • @target(AnnotationTypeOrIdentifier) to capture annotation attached to the target object associated with the captured join point.
  • @args(AnnotationTypeOrIdentifier1, AnnotationTypeOrIdentifier2, …) to capture annotation attached to the arguments associated with the captured join point.

Like this(), target(), and args() pointcuts, the proposed pointcuts take two forms: one that specifies a type and another that specifies an identifier. The first form is used to make join point selection only, whereas the second form is used to also collect the annotation instance as a context. For example, the following pointcut matches all the join points with @Transactional annotation:

pointcut transactedOps() : @interface(Transactional);

whereas the following also collects the annotation instance to use inside advice (just like any other context)

 pointcut transactedOps(Transactional tx)
    : @interface(tx); 

The context collected in this fashion may be used in an if() pointcut. For example, the following pointcut captures only join points that have @Transactional annotation with the kind property set to Required.

pointcut transactedRequiredNewOps(Transactional tx)
    : @interface(tx) && if(tx.kind() == RequiredNew);

Of course, an advice may use collected annotation instances just like any other collected context:

Object around(Transactional tx) : transactedOps(tx) {
    TransactionalKind txKind = tx.value();
    ...
}

Since an element may carry more than one type of annotations (but never two annotations of the same type), the proposed syntax allows using @interface, @this, @target, and @args multiple times in the same pointcut. The following pointcut captures join point with both @Transactional and @Idempotent annotations:

pointcut idempotentTransactional()
    : @interface(Transactional)
      && @interface(Idempotent)

New declare annotations syntax

This new syntax allows attaching annotations to program elements in crosscutting fashion. This syntax resembles the existing declare soft syntax. Adrian Coyler has blogged about this syntax. I have also presented the same idea in JavaOne ‘04. The only difference in the syntax proposed here is switching places between the annotation type and the pointcut to better match the declare soft syntax:

declare annotations: <AnnotationInstance> : <pointcut expression>;

As an example, the following declaration associated a new @Transactional annotation with property kind set to Required to the Account.debit() method:

declare annotations: @Transactional(kind=Required)
    : execution(public void Account.debit(..))
      || execution(public void Account.credit(..));

It should be probably a compile-time error if declare annotations statement would result in multiple annotations of same type for a program elements (much in line with declare parents producing errors if multiple inheritance of classes would result).

Modifications to reflection API

Add new methods in org.aspectj.lang.JoinPoint interface to access annotation instance reflectively.

public interface JoinPoint {

    … current methods …

    public <A extends Annotation> A getAnnotation(Class<A> annotationClass);
    public Annotation[] getAnnotations();

    public <A extends Annotation> A getThisAnnotation(Class<A> annotationClass);
    public Annotation[] getThisAnnotations();

    public <A extends Annotation> A getTargetAnnotation(Class<A> annotationClass);
    public Annotation[] getTargetAnnotations();

    public <A extends Annotation> A[] getArgsAnnotation(Class<A> annotationClass);
    public Annotation[][] getArgsAnnotations();
}

That’s it for now.

Posted in Technology | Comments Off

Hello World!

Finally, I started to blog! More to come soon…

Posted in Technology | 1 Comment