In a previous post I wrote about code quality: in a few words, I believe in static-checking. Static means without executing the program. In a software process point of view, this would imply before runtime, in other words at compile-time. For a developer, it can be very useful to have such a verification simply with a compilation, without executing a specific tool (by the way, some very interesting software of that kind are available, just Findbugs for example).
Here is the point: how would it be possible to proceed that kind of control without rewriting a compiler from scratch ?
The Java platform provides a very interesting feature to perform such operations: annotations (JSR 175). These are metadata defined as java types. Annotations have been introduced in the Java language starting with Java SE 5. Annotations can be processed at compile-time or runtime.
The Sun Java SE distribution provided from the starting point a facility for annotation processing at compile-time called APT (for Annotation Processing Tool). This was a vendor-specific feature (in Sun packages) executed in a specific and eponymous command line tool.
Since Java 6, that function is part of the platform with JSR 269 (javax.annotation.processing package, reference implementation part of the Java SE distribution). The contributed processing can be executed along compilation. With Java SE 8, the historical APT packaging and specific tool is removed (after deprecation in Java SE 7).
If the topic seems basic for the Java platform, there is a lack of exhaustive documentation for annotation processors development. I found some precious informations in Using Java 6 processors in Eclipse , a blog post by Carl-Petter Bertell . The Eclipse platform provide very precious functions with the JDT-APT project.
A very interesting presentation at EclipseCon 2007 by Walter Harley , Gary Horen and Jess Garms from BEA systems develops many important points about compile-time checking: what could be done with annotation processors and what requires more. For example, the processor does not provide the structure of the AST and thereby does not allow flow analysis.
A processor must implement the javax.annotation.processing.Processor interface. The implementation should be specified to the platform using the SPI system. An abstract class AbstractProcessor is provided to help implementations.
In a tutorial about annotation processing, Alex Collins details the implementation of a compile-time processor for the @Transactional annotation of the spring framework .