Aspectivity


3/9/2005

AOP and metadata: A perfect match, Part 1 published

Category:

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.


3/7/2005

Metadata for language extensions

Category:

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.


3/3/2005

NFJS 2005 season starts tomorrow

Category:

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.

Powered by WordPress

Copyright © 2004 Ramnivas Laddad. All rights reserved.

CodeCamp at FootHill College.  Click Here for Details and Registration