InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

John Heintz on Adding Behavior to Java Annotations

Posted by Srini Penchikala on Aug 11, 2008

Sections
Development,
Architecture & Design
Topics
Java ,
AOP
Tags
Annotations ,
AspectJ ,
Metaprogramming ,
AOP

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),
  • Class (data is kept in byte code, not accessible at runtime), and
  • Source level (not kept by compiler).

The recent versions of several popular frameworks like EJB3, Hibernate, Spring, Seam, Struts 2, RIFE and JAX-WS support the Annotations. John discussed three types of Annotation Processing Options:

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.

Bytecode transformer examples include AspectJ, Spring, Hibernate, CGLib, Javassist, ASM, and BCEL.

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:

  • Annotate the highest level of abstraction possible (e.g., class, not method)
  • Use sensible defaults and annotate only exceptions to a rule. Also, minimize need for parameters.
  • Implement Annotations as complementary to "Convention over Configuration" principle (e.g. in Spring).
  • Use Reflection to augment existing frameworks (e.g., testing).
  • Utilize Javassist and CGLIB frameworks for generating new objects and for low-level, highly tuned bytecode transformation.
  • Use APT for generating non-code artifacts.

Srini Penchikala currently works as Security Architect and has 17 yrs of experience in software product management.

Another nice option by Rodolfo de Paula Posted
  1. Back to top

    Another nice option

    by Rodolfo de Paula

Educational Content

New-age Transactional Systems - Not Your Grandpa's OLTP

John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.

Cool Code

Kevlin Henney examines code samples to see what can be learned from them starting from the premise that one won’t write great code unless he knows how to read it.

Collaboration: At the Extremities of Extreme

Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.

Yesod Web Framework

Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).

Transactions without Transactions

Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.

Attila Szegedi on JVM and GC Performance Tuning at Twitter

Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.