Featured in
Architecture & Design

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Featured in
Operations & Infrastructure

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Featured in
Enterprise Architecture

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

John Heintz on Adding Behavior to Java Annotations

Custom annotations are a great way to add common reusable behavior to Java applications. But the developers need to follow some guidelines and best practices to identify the areas in the application where using Annotations is a better design solution than other options such as in-line code or using an Interface. John Heintz from New Aspects did a presentation at the recent No Fluff Just Stuff (NFJS) Central Ohio Software Symposium (COSS) on different design techniques for adding behavior to Java custom Annotations.

In the presentation, John gave a walk-through of byte-code and meta programming techniques and an overview of how metadata in Java applications has been managed from the earlier versions of Java, using Properties files, XML, and now Annotations. He mentioned that JSR-175 was formed to provide a metadata facility for the Java language and in Java 5, Annotations were added to the language.

Defining Annotations is similar to defining the Interfaces (Annotations are declared using @Interface type). Annotations can be applied at package level or on a class member (field, method, constructor) or even a method local parameter.

The retention policy, which is an important part of implementing Annotations, is based on how long the data needs to be kept in memory. There are three different types of retention policy:

Runtime (where data is retained always and accessible through reflection),

Generators: This annotation processing option works by reading the source code and generating new source code or modifying existing source code, and non-source code (XML, documentation, etc.). The generators are typically rely on container or other programming convention and they work with any retention policy.

Some of the generators examples are Annotation Processing Tool (APT) and Processors, XDoclet, Spoon (extensible compiler for Java), and APT-Jelly (which is a templating library). APT doesn't allow you to modify the source code but it's useful for generating auxiliary artifacts (like WSDL, Documentation).

Bytecode Transformers: These annotation handlers parse the class files with Annotations and emit modified classes and newly generated classes. They can also generate non-class artifacts (like XML configuration files). Bytecode transformers can be run offline (compile time), at load-time, or dynamically at run-time (using JVMTI API). They work with class or runtime retention policy.

Runtime reflection: This option uses Reflection API to programmatically inspect the objects at runtime. It typically relies on the container or other programming convention and requires runtime retention policy.

Runtime reflection examples are libraries like Java 5+ reflection and Commons Attributes. Testing frameworks like JUnit and TestNG use runtime reflection for processing the Annotations.

John used a sample Java application to demonstrate the implementation of custom Annotations using different design techniques like APT, Javassist, AspectJ, and Reflection (which uses java dynamic proxies). He also showed how to add behavior to classes, fields and methods and talked about annotating Types and Methods with Aspects.

John talked about the benefits of Aspect Processing like ease of implementation (good tool support), fine-grained semantics where it can influence method calls, even field access (unlike reflection and APT), integrating annotations from multiple libraries, and the support for domain-specific abstractions. He suggested that if the java code can be implemented as an interface, then the developers should go with that design instead of using Annotations. He cautioned the developers to not use custom Annotations for everything because a POJO (Plain Old Java Object) is better than a HAJO (Heavily Annotated Java Object). Other best practices mentioned in the presentation are: