Welcome!

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

Related Topics: Java

Java: Article

Java Annotation Facility - A Primer

JDK 5 Has Changed Source Code Generation in a Seminal Way

Before tackling how to generate code or other dependent files such as deployment descriptor, we should clarify a couple of aspects presented in the code snippet above. The StrutsAction annotation type defines many elements but only a few of them were actually declared in the real annotation. This is perfectly valid because the elements that don't have a value declared will take the default value defined in the annotation type. In this case most of the values defaulted to an empty string but the scope element has a default value of session. So if the developer doesn't explicitly specify the value, the default value will be used. In the StrutsAction annotation type, we also have the return type for the forward element as an array of StrutsActionForward elements. So annotation is done by separating the values by a comma wrapped in braces.


forward = {@StrutsActionForward( ... ),
@StrutsActionForward( ... ) },

In this code snippet two action forward element are specified and both of them are enclosed by a brace separated by a comma. Now that we've talked about annotation types and annotation, the core concepts of annotation have been pretty much covered.

Generating Code/Supporting Files
The final steps in the process are the procedures for generating code or support files like deployment descriptor. This could be the hardest part depending on the complexity of what we are trying to do. If we are generating source code based on annotation information then we need to have some kind of parser generator to generate the code. JavaCC hosted at www.java.net is an excellent parser generator implementation. Since we are generating an XML file, we used JDOM API to generate the deployment descriptor for struts.

There are two ways to do the code generation. The first is to write a driver code that uses the reflection API and the annotation API to figure out what annotations are present and then operate on them appropriately. The other is to use the annotation processing tool bundled with the JDK to process the annotation.

In the section above we explained how the annotation processing tool works. The annotation processor that's returned by the factory does the actual work of generating code. In the core processing we loop through the annotation types and have a visitor based on the Gang of Four's visitor design pattern do the work. This visitor processes the annotation on the class declaration, method declaration, package declarations etc. and does the file generation.

The code snippet for the factory, annotation processor and a simple visitor is as follows:


public class StrutsConfigGenerator implements
AnnotationProcessorFactory{
private static final Collection<String>
supportedAnnotations
= unmodifiableCollection(Arrays.asList("*"));
private static final Collection<String>
supportedOptions = emptySet();
public StrutsConfigGenerator() {}

public Collection<String> supported
AnnotationTypes() {
return supportedAnnotations;
}

public Collection<String> supported
Options() {
return supportedOptions;
}

public AnnotationProcessor get
ProcessorFor(
Set<AnnotationType
Declaration> atds,
AnnotationProcessor
Environment env) {
return (AnnotationProcessor)new
WebGeneratedAp(env);
}

private static class WebGeneratedAp
implements
AnnotationProcessor {
private final AnnotationProcessor
Environment env;
WebGeneratedAp(AnnotationProcessor
Environment env) {}

public void process() {
for (TypeDeclaration typeDecl :
env.getSpecifiedType
Declarations()){
// GoF visitor Design Pattern
applied here!
typeDecl.accept(get
DeclarationScanner(
new WebGeneratorClass
Visitor(), NO_OP));
}
}
private class WebGeneratorClassVisitor
xtends
SimpleDeclarationVisitor {
public WebGeneratorClassVisitor(){ }

public void visitClassDeclaration(
ClassDeclaration d)
{
/ /Do some meaningful work here!!!
}

// You could have more specific declarations here
}
}
}

An important thing that we need to take note of is the getProcessorFor method in the factory. This method returns the annotation processor and, in our case, is an instance of the WebGeneratedAp class. This class extends AnnotationProcessor and implements the no args process method. Here we loop through all the type declarations and then have the type declaration accept our visitor. Our visitor is WebGeneratorClassVisitor and has methods to handle the areas where annotations occur like class declaration, method declaration and package declaration. It's here that we read the annotation, find out what the value is and operate on it accordingly. The complete working copy of the source is provided along with this article.

The final step in the process is to invoke the Annotation Processing Tool. This is typically done through the command line as follows:


apt -cp [Classpath] -nocompile
-factory com.jdj.article.gen.StrutsConfigGenerator
-Astruts-config=F:\Article\Dev\Annotation\
generated\struts-config.xml <path>\
ExampleAction.java

Comments (6) 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
udaykirand 09/08/08 10:15:23 AM EDT

Really Excellent Information. But i have some doubts. initially i have some aversion towards annotations but after reading this article i develop some interest on it. later my R & D i want to create an annotation which is like @Singleton when ever i applied this annotation for a class then i want to make a class as singleton class. could you please help me out from this scenario.

in the same way @ThrowException(exceptionType="ArithmeticException.class")

many more ideas but i couldn't able to move in forward direction because there is no much information about annotations in Google also.
even no where i found the source code of this article. if you have any please send me complete source code with compilation and execution instructions. please please its really great help for me.my id is udaykiranmca@gmail.com

Thanks,
udaykiranmca@gmail.com
please send to this mail id .

Terry Corbet 08/06/06 06:00:49 PM EDT

This is a critique for the editor, not the author.

A primer that uses for an example something that requires experience with Struts is not what you should have provided. Ok, so the guy you got to do all the hard work happened to be interested in solving a Struts problem, but your job, as editor, should have been to carefully think through the issues of documenting this new Java facility and providing examples with as little dependence upon some specific toolkit-framework-environment as possible. With Mustang about to add to the value of annotation, I am sure there is much need for carefully-thought-out articles demonstrating valuable, incremental information. When K&R contrived 'Hello World', it was after thoughtful consideration about learning processes. Combined with the fact that the source code was not correctly provided, the overall impression is that you, as an editor, just thought you could get something for nothing and pass it along where enough Google hits would provide the mass of advertising that is blinking all around me as I enter this suggestion.

Vish 07/21/05 10:00:00 PM EDT

Bob,

Sorry about that. Can you send me an email at unicode@yahoo.com, and I will send you the src

Thanks,

Bob Shewan 07/21/05 05:40:07 PM EDT

As Neil noted there isn't any source code in the zip file. Would you be kind enough to send what you have.

Thanks

Bob Shewan

vish krishnan 03/13/05 10:23:16 AM EST

Neil, sorry about that. Send me an email and I will send you all the source that I have got. My email is unicode at yahoo dot com (OR) krviswanath at Deloitte dot com

thanks

Neil Hornbeck 03/11/05 07:33:41 AM EST

The source zip file Viswanth1003.zip only contains compiled code.