Tuesday, August 5, 2008

Annotations and Agility

Frameworks are commonly configured through external properties either in the form of textual XML files or property *.ini files. While this allows applications to be configured without having to change code, maintaining these files in a team environment can inhibit agility. Attribute Oriented Programming moves configuration information out of centralized property files and puts this meta information closer to relevent source code elments. This information can then be picked up at design and/or runtime and used by a framework.

The XDoclet framework poineered the ability to define useful attribute libraries that support many frameworks. XDoclet was so succefull, that Annotations, another name for attribute, were introduced as a real language construct in the Java 5 SDK.

Quick Java Annotation Primer

Annotations are defined just like a Java class, interface element, they are defined in a package definition and can be targeted towards Class, Variables, or Methods. Additionally, they can be defined with a retention policy, keeping them in compiled class binary files for runtime processing or stripping them out when source is compiled.

Lets create an annotation and put it to use. Consider a @Info annotation that is targeted towards class definition. It simply annotates a class with an owner data and wether a class has been code reviewed. This annotation is defined in java annotation declaration shown below.



@Target({ElementType.TYPE})

public @interface Info


{
String owner() default
"NO-OWNER";
String notes() default "";

String reviewed default “NOT-REVIEWED";


}





You can see the @Info annotation applied to a class definition below.





@Info(owner="dpitt")


public class MyClass {
String attribute = null;
}





The usefullness of this annotation is twofold. First, using the supplied annotation processor source can be scanned and a report generated indicating whether a class has been reviewed. Second, an exception handler can be defined that will sense for the @Info annotation in a stack trace and report who's reposinble for the exception. Source for this exception handler is shown below.




public class ExceptionHandler {
public static void handle(Throwable e)
{
// determine where exception occurred, ignoring sy stem
classes StackTraceElement[] st = e.getStackTrace();
f or (StackTraceElement ele : st) {
String className =
ele.getClassName();
Class cls = null;
try {
cls = (Class) Class.f orName(className);
} catch (ClassNotFoundException e1) {
System.out.println(e1); }

// sense for @Info annotation

if (cls.isAnnotationPresent(Inf o.class)) {
Inf o inf o = (Inf o)
cls.getAnnotation(Inf o.class);
System.out.println("=== Owner of this Exception is: " + info.owner() + " ====");
System.out.println("Error Occurred :" + className);
System.out.print(e);
}
} } }



Agility

Popular frameworks such as Hibernate and Spring have introduced annotations as an option for configuration instead of using XML files. With Hibernate annotations or javax.persistent Annotations can be used to define mapping attributes. An example mapping a class to a table is shown below.



@Entity
@Table(name = "EMPLOYEE")
public class Employee
{



@Column(name = "FIRST_NAME")

public String getFirst()
{...


@Id
@GeneratedValue
@Column(name = "ID")
public Long getId()
{...




Annotations provide agility in development teams by not eliminating the need for developers to reconcile and define framework meta data in property file mechanisms. Eliminating these files may not seem like a big deal, but with a team of 10 developers all having to add and synchronize configuration files. Allowing configuration info to live close to source elements, lets developers spend more time writing software for a given problem, and not chasing down configuration issues.