Welcome!

Java Authors: Maureen O'Gara, Liz McMillan, Walter H. Pinson, III, Yakov Werde, Tony Bishop

Related Topics: Java, IT SOLUTIONS GUIDE

Java: Article

Kicking the Tires on Java 5.0

Building an aspect-oriented framework based on annotations

"BaseInjector" holds a type-safe linked list of "BaseInjector" types. Recall the class that does the bytecode engineering and introduces method calls either before or after the annotated method. The code that's introduced during bytecode engineering is based on the "BaseInjector" class and is resolved at runtime via the Spring framework. So from a developer's perspective to introduce code that's executed either before a business method or after a business method, he or she would:

  • Create a class (or classes) that extend "BaseInjector" and implement the execute() method.
  • Annotate the business methods you want instrumented specifying two parameters, the bean lookup key that Spring will use to build your interceptor and the 'pre' or 'post' specification that tells the bytecode engineering code where to tack this interceptor on.
  • Configure your Spring file.
  • Run the application with the appropriate command-line switches that properly run the agent prior to main being called and installs the class-file transformer.
For completeness, here's a snippet of the Spring configuration file that wires up the interceptor. Please note that it's possible to chain together interceptors; Spring will accommodate this quite nicely via its ability to reference other beans under its control and apply them in setters or constructor arguments. Please consult Spring's documentation for more information on this. In this context, the annotation would specify the "nullInjector" as the processBean attribute and either "pre" or "post" for the insertionPoint attribute that designates where the developer intends to have the code executed.

<!-- Null Injector -->
<bean id="nullInjector" class="injectors.NullInjector" singleton="false">
<constructor-arg><ref bean="interestingInjector"/></constructor-arg>
</bean>

At runtime, the injected code looks up the interceptor logic via Spring based on the value of the "processBean" attribute specified on the annotation being processed. Once retrieved, the injected code calls the "execute()" method on the bean that in turn executes whatever code happens to be in the "execute()" method. This pattern is fairly common in application server environments whereby the container must execute a series of interceptors either before or after the target business method. For instance, a J2EE container may do this on an EJB call to facilitate security, logging, statistics, and the like before actually executing the target method on the bean itself.

Summary, Conclusion, and the Ubiquitous Product Disclaimer
There are some really notable inclusions in the latest release of Java. At the very minimum, developers should embrace generics as a way of making code safer and more readable. Generics also support a tighter contract between caller and service that's generally always a good thing. The annotation framework shows great promise for tool and framework writers. EJB 3.0 threatens to lean heavily on annotations and I suspect this may cause the pendulum of "xml configuration hell" to swing the other way. Developers will be able to introduce metadata closer to the source, which will eliminate the proliferation of deployment and runtime files that seem to be on the increase. Sun also seems to be inventing ways to open the JVM up a little to framework authors and tool builders; as evidence we've looked at some of the new hooks available to us for class loading and on-the-fly class manipulation. I encourage developers to poke around the "java.lang.annotations," the "java.lang.instrument," and the "java.lang.management" packages. It's this "poking around" that inspired some of the goodies in this article and the tiny framework that subsequently developed.

I also encourage you to download, look at, hack, and run the source code available with this article. I've included pertinent snips of code, but the gist of this framework is best realized by looking at the entire landscape.

Whoops, I almost forgot the product disclaimer. I wanted to make sure that I stated that this framework is a conceptual work and that I do not represent it as a full-blown aspect-oriented system. I feel the concepts here are viable and could be developed into a very rich, robust system but as set forth here are primarily intended as a backdrop to the new capabilities of Java.

Resources

Comments (3) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
slopzster 07/13/05 11:30:22 PM EDT

fantastic article, very thought provoking -- kudos. Can you comment on potential performance related issues in instrumented components that have high availability requirements?

Boris 06/29/05 11:45:06 AM EDT

I'm sorry, but I cann't find link to sources
of this cool article on the web pages.

Peter Braswell 06/24/05 01:03:39 PM EDT

This article will survey some of Java 5.0's new features and put them into practice through example. We'll build up a lightweight aspect-oriented system based on annotations to showcase what's new in 5.0. Some of these features you may be familiar with, some you may not. I've attempted to mix the obvious with some of the obscure. We'll examine some of the new hooks that the JVM has exposed for class loading, which makes the once dreadful work of bytecode manipulation during class loading much easier. In the "obvious" column, we'll look at generics and how they enable us to write more robust and sane programs, especially when dealing with collections. Perhaps the most notable aspect of Java 5.0 that we'll examine is the annotation framework. Annotations allow developers to inject metadata into their applications. We'll use this feature to demark classes we want manipulated at load time. To put this all in context, we'll create a lightweight framework that will manipulate classes as they are being loaded to enable logging, security, BAM (business activity monitoring), or any number of other scenarios that have yet to be dreamed up