March 18, 2009

Tracking Requirements using Annotations for Java Projects

Tracking requirement has been always a major challenge in big projects. Requirement Traceability Matrix (RTM) document is never up-to-date. The team looses interest and lacks the rigor to maintain RTM for various reasons.

In this article we will see how to achieve a developer friendly way of tracking requirements directly in the Java source code with the “Annotations”; a new feature introduced in JDK 5.0.


Introduction

Annotations (or Metadata) were formally introduced as part of JSR-175, approved in Sept 2004 into Java 5.0 (JDK 1.5 version).

Annotations were always present since earlier version of JDK but in ad-hoc forms like @deprecated javadoc tag, transient modifier (indicating that a field should be ignored by the serialization subsystem) etc. JSR-175 standardized it and JDK 5.0 gave the developers the power and flexibility to define custom annotations.

Also Annotations gained importance because of its ability to generate boilerplate code for many frameworks. They hugely became popular because of the technical requirements imposed by some heavy weight runtime environments like EJB 2.1, JAX-RPC etc. Many of the artifacts like interface, deployment descriptors, implementation classes and other related files are easily generated by the annotation processor tool by inspecting the “decorated” source code elements

What are annotations?

In simple language, annotations are “metadata” added directly to the source code.

This metadata can be retained in the class files generated by the java compiler and are reflective in nature. Classes, methods, fields, packages can be annotated.

Annotations have a special syntax and rules of its own. Look into the resources section for some links related to tutorials, articles on the web

What are annotations?

In simple language, annotations are “metadata” added directly to the source code.

This metadata can be retained in the class files generated by the java compiler and are reflective in nature. Classes, methods, fields, packages can be annotated.

Annotations have a special syntax and rules of its own. Look into the resources section for some links related to tutorials, articles on the web.

Hypothetical Example:

Let’s assume that your company is maintaining a large enterprise application for a client. The application has been delivered a year back and the application is currently in the maintenance phase. The usual maintenance activities are bug fixing, back up activities.

The original developers have been rotated and the majority of maintenance team is relatively new, having a rudimentary knowledge on the application.

Now after a year or so, the client plans to come up with a next version of the application with a set of new features based on the market feedback, users inputs etc. The client comes up with about 80 – 90 new requirements and requests for a proposal to accommodate these new features in the version 2 of the application.

The version 1 requirements were in a separate word document - outdated. The bug fixes and minor enhancements requirements which had come later were scattered in the team’s mail box, bug tracking tool. The requirements traceability matrix was in a very poor state, pretty outdated. The team lacked the rigor to update this on need basis, always postponing it. The end result: RTM document became so outdated that any wanting developer lacked the motivation to do it.

The Project Leader (who is again new, for whatever reasons) has to respond back to the client with the proposal for these new set of requirements. He and his team are stuck and have no clue where to start, how to find which requirement impacts which part of the code.

The above is a little dramatized example, but I have seen such cases.

Although the team consists of sharp developers, they do not show the same rigor in updating the RTM document as they show the passion for coding.

How do the annotations help?

It is the developer friendly approach of maintaining the requirements as “metadata” as part of the source code. The code review process can ensure this.

Tracking requirements using annotations directly in the code helps:

1. Requirements are always in the current state

2. No need of RTM

3. Reports on the requirements can be generated on the current source code

4. Impact analysis / estimation of new features and tasks would be easier

5. No need to invest, manage, train in an additional commercial tool

6. One place maintenance


Moving on

Firstly, let us define an annotation, which will be used by end users i.e. developers.


Annotations are very similar to Java interface definitions. Notice the @ symbol before the interface keyword. In the above code snippet, we have defined an annotation by name Requirement (or it could be named as Feature, in agile lingo). Most of the properties defined above are self explanatory. Basically the properties defined above are to track which use case, project, module does this requirement belong, whether it is a high priority or a functional kind of requirement etc.

Also if you observe the above code, our Requirement annotation definition has also been annotated with annotations - @Target which is available by default in java.lang package. @Target tells us that Requirement annotation can be used only for classes, methods, constructors, packages and instance fields

Example in use

Let us define a simple Java interface & apply the Requirement annotation.




The above code snippet is pretty much self explanatory; shows how the code would look when Requirement annotation is applied to a Java interface WorkDaysCalendarCalc with two service methods: isWorkDay() & getWorkDayNumberInCurrentYear(). Also notice that some of the properties like projectName, type of Requirement annotation etc have default values. These need not be declared.

Annotation Processing

The next step would be to process these annotations. Running the annotations is not done with the usual java command, but with a tool called apt (annotation processing tool) introduced in Java SE 5.0.

Java SE 6 has this capability built it in the compiler, thanks to JSR-269.

Let’s see some Java 6.0 code of our Requirement annotation processor





Annotation processors in Java 6.0 have to extend AbstractProcessor of javax.annotation.processing package and override the process method.

The above RequirementAnnotProcessor processes only those Java files which use Requirement annotation. This restriction has been put by @SupportedAnnotationTypes("com.req.annot.Requirement").

javac compiler calls the process method of our RequirementAnnotProcessor whenever it encounters any Java file which uses or imports com.req.annot.Requirement annotation.

The first step would be to compile out RequirementAnnotProcessor.java.

The below figure should give an idea on the package structure.





Open a command prompt, and navigate to the package com.req.annot and compile RequirementAnnotProcessor.java. Please see the below image for more details.





Output

The next step after compiling the Annotation processor would be to process the Java file, WorkDaysCalendarCalc.java, which uses our Requirement annotation.

Navigate to the src folder and issue the following command:

D:\Basav\eclipseWorkspace\TestReq\src>javac -processor com.req.annot.RequirementAnnotProcessor com\test\service\WorkDaysC

alendarCalc.java

Here -processor switch tells javac to use annotation processor before compiling the code

You should see the following output:

-------------------

Received Annotations :[com.req.annot.Requirement]

Processing annotation :com.req.annot.Requirement

Elements for that :[com.test.service.WorkDaysCalendarCalc, isWorkDay(java.lang.String,java.util.Date), getWorkDayNumberIn

CurrentYear(java.lang.String,java.util.Date)]

-------------------

Received Annotations :[]



The process method of RequirementAnnotProcessor is called for each Java file containing Requirement annotation, in out case WorkDaysCalendarCalc and prints the elements (classes, methods etc) which use the Requirement annotation.

The process method is the worker bee of any annotation processor. In the above rudimentary example, the process is just printing all the elements which declare out Requirement annotation. This method would be actually enhanced to generate an xml file for e.g. something like the below structure. This is just an indication; the output report can be customized based on the project needs.





Conclusion

To sum up, this is an attempt to explore the possibility of tracking requirements and keeping the requirements as up-to-date as possible using annotations. From past couple of years agile fever is catching up. Lots of Java projects are heading the agile way, with shorter iterations, less up front design and diving directly into the code with small set of initial requirements, taking baby steps. This would definitely add a step to the developers but the returns would be huge.

Thanks for reading.

References

http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html

http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html

http://www.jcp.org/en/jsr/detail?id=175

http://www.jcp.org/en/jsr/detail?id=269