Writing and processing custom annotations - Part 1

In this first of a four-part series, Lee Chuk-Mun shows you how to develop and process custom annotations.
Written by Lee Chuk-Munn, Contributor
Over the next few weeks, we'll look at how to develop and process custom annotations.

  • Part 1: Designing the  @Option Annotation

  • We will talk about a typical scenario in which an annotation can help simplify our programming chore. 

  • Part 2: Developing the  @Option Annotation

  • We will look at some considerations in developing an annotation; more specifically we will look at how we will develop our @Option annotation

  • Part 3: Processing the  @Option Annotations

  • In this part, we will develop an options processor to process our  @Option annotation

  • Part 4: Using the  @Option Annotation

  • In this final part, we will look at how to use the annotation that we have developed.

    Let's get started
    Designing the  @Option Annotation

    Annotation or metadata is one of the new features that was introduced in the Java SE 5 (aka Tiger). With annotations, you can mark all or parts of your Java code with information such as copyright, modification date, author name; or configuration information such as database names, Web services, etc. You can think of annotations as information meant for other applications to read, understand and process. 

    Most Java applications that we write require some sort of command line option like:

    java FileTransfer -filename myfile.txt -server myserver.com

    In this case -filename and -server are option switches to FileTransfer. However, parsing the command line options, though simple, can be laborious and boring.

    We will develop an annotation to help us automatically generate an option processor; the option processor will parse the command line and report any erroneous option switches. Note: this idea is based on args4j developed by Kohsuke Kawaguchi. You can find his original blog on args4j here.

    Before we go into the details of implementing the annotation, let us look at how we are going to use it first. This will give us a better understanding of what our annotation is doing and what are the pieces that we are going to write.

    1. Assume we have the following command line that we wish to parse:
    2. java FileTransfer -filename myfile.txt -server myserver.com

      -filename and -server are the two option switches and myfile.txt and myserver.com are their option values respectively.

    3. We write a Java class with two public members of the type java.lang.String. The number of members should correspond to the number of option values. We will call this type of class for holding option values an option bean. Here is an example of an option bean class called FileTransferOptions
    4. public class FileTransferOptions {
         public String fileName;
         public String server;

    5. Now we use our custom annotation called @Option to map the members in the option bean to the their corresponding option switches like so:
    6. public class FileTransferOptions {
         @Option(switch="-filename") public String fileName;
         @Option(switch="-server") public String server;

      Option values will now be stored in the corresponding members; an example would be the String value myfile.txt will be stored in fileName

    7. The option bean class will now be compiled with our custom annotation processor:
    8. javac -processor OptionsProcessor

      The -processor option specifies a custom annotation processor to use; in our case OptionsProcess is that custom annotation processor.

    9. OptionsProcess will generate a class called FileTransferOptionsProcessor with a single static method called process( ); this method has the following signature:
    10. public static FileTransferOptions process(String[] args)

      The name of the processor class and the return type of process ( ) is dependent on the option bean class. If the option bean class is called SuperDuperOptions, then the processor class will be called SuperDuperOptionsProcessor and process ( ) will now return an instance of SuperDuperOptions.

    11. Here is how we can use FileTransferOptionsProcessor
    12. public class FileTransfer {
         public static void main(String[] args) {
            //Pass the entire command line to be processed
            FileTransferOptions opts = FileTransferOptionsProcessor.
            //Do something with opts

    Lee Chuk-Munn has been programming in the Java language since 1996, when he first joined Sun Microsystems in Hong Kong. He currently works as a senior developer consultant and technology evangelist for Technology Outreach at Sun in Singapore. Chuk's focus is in Java APIs, Java EE, Java SE, and Java ME. Chuk graduated in 1987 from the Royal Melbourne Institute of Technology in Melbourne, Australia, where his favorite subject was compiler theory.

    Editorial standards