@Java

A Java Annotation Extension


Questions and issues to Walter Cazzola.

A brief introduction to Java Annotations

Among the features introduced by Sun in Java 5.0 (codename "Tiger") there is a new facility that allows you to enrich your code with meta-data. 'Meta-data' is a word that means "data about data" and nowadays we can find application of this concept in virtually every area which involves the manipulation of digital information.

A common example of meta-data can be found in the digital camera's picture files. These files contains, beside the picture itself, some information (the dubbed EXIF data) that describes the context in which the shot was taken. This includes (but is not limited to) the camera brand and model, the optical settings (exposition time, sensibility, lenses information) and the date and time of the shot. All these data do not change in any way the content of the image itself or the way it appears: they just describe some aspects that are not intrinsically encoded into the picture, i.e., they are extra data on the main data (the picture).

If we move the same concept into the Java programming context, we can say that meta-data are additional information about the elements that compose the program (classes, class methods, class fields, packages and so on) that do not alter the element's semantic itself. Meta-data just "decorate" them, or, to use the proper term, "annotate" them. After which, the term annotation.

Here is an example of a very simple annotation. In this case we want to associate a to-do list to a class. We can write something like that:


   @ToDo("Still to implement everything!!!")
   public class MyClass {}
 

and here is how the ToDo annotation has to be declared:


   public @interface ToDo {
      String value();
   }

As you can see from the above example, annotation are a special kind of Java interfaces. The ToDo annotation in the code is preceded by the special character '@' (and that is the reason for the @ in the @Java name), and this similarity to the Javadoc tags (which the character @ reminds) is not by coincidence.

Indeed, annotation and Javadoc share the same general idea: add meta-data to the code. However they differ deeply in their intent: Javadoc is a specifically-designed mechanism which aim to produce API documentation. Annotations are, on the other side, a general purpose tool. Although Sun provides some specific annotation with specific meaning, you are able to define your own annotation type.

However, the most important difference is in how the meta-data described by the two tools are stored and handled.

Javadoc tags can be read exclusively by ad-hoc tools, and directly from the source code. All you can do with them is to generate static HTML pages as a programmers reference. On the contrary, annotations are typed elements of the Java language (as interfaces are), and as such they can be treated. This implies that annotations can be stored directly in the class bytecode opening a new wide range of opportunities to retrieve the data.

Some of them are:

What is @Java? And How does it work?

In standard Java, annotations can be applied only to element declarations such as class, field, and method declarations. Of course, this is enough to support most of the meta-data applications but hamper their use in some specific contexts like profiling, reverse engineering and so on.

The @Java project aims to increment the granularity of the scope of the annotations providing an extended Java syntax and an extension to the reflective methods. In addition to the declarations, @Java allows you to annotate:

Look at the following examples to see the new syntax (in red) in action:


   import java.lang.annotation.*;

   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.EXPRESSION)
   public @interface Predicate {
     int value() default 0;
   }

   public class DoSomething {
     ...
     if (@Predicate{i==0}) return 0;
     ...
   }

Here we have annotated the boolean expression i==0 with the annotation @Predicate to say that it is a predicate.


   import java.lang.annotation.*;

   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.BLOCK)
   public @interface Validation {
     String value();
   }

   public class Login {
     final static int MIN_USERNAME_LENGTH=4;
     boolean checkUserName (String username) {
       @Validation ("Check username length") {
       if (username.length() < MIN_USERNAME_LENGTH)
         return false;
       }
       return true;
     }
   }

In this example we have annotated a block of code whose purpose is to validate a username string, hence we used the @Validation annotation.

Of course, block and expression annotations can be retrieved through reflection as well as standard annotations.


  import java.lang.annotation.*;
  import java.lang.reflect.*;
  import atjava.lang.annotation.*;

  public class TestReflection {
    public static void main(String args[]) throws Exception {
       Method m = Login.class.getDeclaredMethod("checkUserName",
                                         new Class[]{String.class});

       Annotation[] ca = m.getBlockAnnotations(Validation.class);
       System.out.println("annotation: "+ca[0].toString());

       AnnotatedBlock[] ab = m.getAnnotatedBlocks(Validation.class);
       System.out.println("annotated block (source): "+
                    ab[0].getBodySourceCode());
    }
  }
  
To compile a @Java program you have to use the ``atjavac`` compiler whose options are the same of ``javac`` . The program can be executed by the standard Java virtual machine.

  [12:44]cazzola@thor:~>atjavac TestReflection.java
  [12:45]cazzola@thor:~>java TestReflection
  annotation: @Validation(value=Check username length)
  annotated block (source):
      if (username.length() < MIN_USERNAME_LENGTH)
        return false;
  
As notable from the above example a few enhancement are available for block and expression annotations, e.g., you can get the source or the bytecode of the annotated code.

A complete list of the reflective API is available at the @Java API Reference Page.

Future evolutions

At the moment @Java is in a pre-release status. Everything works, but the whole project requires some more tidying in order to be released as 1.0. Currently @Java works on the JDK 5, but a port to the JDK 6 is in progress. We'll release it here as soon as possible.

A plugin for Eclipse and few language extensions are under development, as well.

Getting started with @Java

@Java is currently distributed as a GNU/Linux RPM package file. It can be installed on every reasonably recent RPM-based distribution. (See at the end of the page for a list of the tested platform).

To successfully install and use @Java you should have the following software properly installed and configured on your system:

Installing @Java involves the following steps:

At this point you can compile your @Java-enhanced source code with the atjavac compiler and run the program through the standard Java virtual machine.

@Java has been tested on the following operating systems:

@Java for Microsoft Windows with a few instructions could be downloaded at the @Java on Windows Page but this release is neither supported nor up-to-date.

@Java Staff

The @Java project is led by Walter Cazzola.

References
  1. Walter Cazzola and Edoardo Vacchi, @Java: Annotations in Freedom, in Proceedings of 28th Annual ACM Symposium on Applied Computing (SAC'13), Coimbra, Portugal, March 2013, ACM Press.

Walter Cazzola

Didactics

Publications

Funded Projects

Research Projects

Related Events








Valid XHTML 1.0 Transitional