BT

InfoQ Article: The Annotation Hammer

by Floyd Marinescu on Jul 25, 2006 |
In this latest InfoQ article, Venkat Subramanium (author of Practices of an Agile Developer) takes a look at Java SE 5 Annotations. What they are, how to create them, and more importantly, how to use and not misuse them.  "The right use of annotations" is a design concern that deserves due consideration in application development - neither blind acceptance nor rejection of it is a good idea.

Read The Annotation Hammer.
"If the only tool you have is a hammer, then everything looks like a nail," goes a saying. While annotations are a good tool, not every situation warrants their use. Most of us have come to dislike XML configuration. However, suddenly, everything in the XML configuration shouldn't become annotation.

Use annotations for what you want to express intrinsically in code. For example, the @Persist annotation in Tapestry is a good example. You want to declare a property of a bean as persistent and Tapestry will take care of storing it (in the session for instance). I would much rather define this as annotation than using a verbose configuration to say the same. The chances are, if I decide not to make the property persistent, much is going to change in the code anyways.
How have you been using Annotations on your projects?

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Spring 2.0 by Corby Page

I am very surprised that current versions of the Spring 2.0 docs are emphasizing the use of annotations to define aspects, rather than XML configuration.

From the docs: Spring's support for @AspectJ aspects is the recommended approach for declaring aspects for use with the Spring AOP framework. "@AspectJ" refers to a style of declaring aspects as regular Java classes annotated with Java 5 annotations.

Aspects are the sort of thing where you are going to want an application-wide view of how they are cross-cutting your application. Without explicit AspectJ tooling support, you are not going to get that if you use annotations.

What's worse is that pointcuts are not very refactoring-friendly. Being able to assess all of your application's pointcuts in a single XML file is a good way to head off errors introduced by refactoring. Hunting down all of your pointcut annotations in individual class files is not a scalable process.

Re: Spring 2.0 by Uri Boness

AOP != Configuration != Meta-data!
It is time for developers to start seeing aspects as first class citizens of the application. You have classes to model concepts and you have aspects to model requirements (architecture requirements, domain requirements, or application requirements). The @AspectJ annotations is not there to configure the aspects, but to define them. I agree that it would probably be best if we could all use AspectJ traditional aspect constructs in our applications, but unfortunately not many tools support it at the moment (e.g. IntelliJ). @AspectJ annotation opens the window for us (IntelliJ users) to leverage AOP support in our applications by using this extremely powerful tool.

Re: Spring 2.0 by Corby Page

@AspectJ annotation opens the window for us (IntelliJ users) to leverage AOP support in our applications by using this extremely powerful tool.


I'm not following you. I'm an IntelliJ user, and I found it a pain in the ass to find all the classes that I had set up with @Aspect, and to track down their associated Pointcuts so I can see who is advising what.

Once I had moved these declarations into a config file, I could survey all of my aspects, and what they were cross-cutting, on a single page on my screen. Much better.

It's all fine and good to say that aspects need to be 'first class citizens', but IntelliJ is not a dedicated AOP development environment, so for right now there are two places we can specify our aspects: configuration or metadata.

Re: Spring 2.0 by Alexandre Poitras

AOP != Configuration != Meta-data!
It is time for developers to start seeing aspects as first class citizens of the application. You have classes to model concepts and you have aspects to model requirements (architecture requirements, domain requirements, or application requirements). The @AspectJ annotations is not there to configure the aspects, but to define them. I agree that it would probably be best if we could all use AspectJ traditional aspect constructs in our applications, but unfortunately not many tools support it at the moment (e.g. IntelliJ). @AspectJ annotation opens the window for us (IntelliJ users) to leverage AOP support in our applications by using this extremely powerful tool.


I agree with you.

Re: Spring 2.0 by Uri Boness


I'm not following you. I'm an IntelliJ user, and I found it a pain in the ass to find all the classes that I had set up with @Aspect, and to track down their associated Pointcuts so I can see who is advising what.


How do you track down classes in the application? or functionality in general? You probably use proper naming strategies/conventions, and well packaging. The same should be done with aspects - good packaging and naming should definitely make it easy to find your way around the pointcuts... actually, IMO defining all the aspects in the application context makes a mess out of it... well... it's much better now with the new namespaces, but still...

Re: Spring 2.0 by Corby Page

How do you track down classes in the application? or functionality in general? You probably use proper naming strategies/conventions, and well packaging.


That doesn't really get around the fact that I want to get an 'application-level' view of what is cross-cutting my application, and I still have to iterate through the aspects one at a time to get it with the annotations. If you use 'proper' organizational practices on your context.xml, you can access all of your aspects in a single, easy-to-read file.

Anyway, I think there is one place we can agree. The annotation support makes it easier for tools like IntelliJ to build plugins and extensions for a dedicated AOP UI that does make aspects a first-class citizen. Once that kind of support is in place, I would be just fine with using annotations.

Re: Spring 2.0 by Tomasz Blachowicz

I've been playing with @Configurable annotation from Spring 2.0 and it looks very nice. When I showed it to my mates, they felt really confused how it all happened :) I run sample application in JBoss AS with runtime weaving and it worked quite well. In general I'm big fun of annotations and I'm happy that Spring guys've started to use them.

What I miss... by Tomasz Blachowicz

What I miss is inheritance of annotations. I hope I was be able to define one generic annotation and then create a bunch of specialised ones with additional attributes. The problem is when you try to write generic code to explore them. Without annotation inheritance it's hard to do it well.

Re: What I miss... by Alex Popescu

I don't know the reasons why inheritance is not part of the annotation spec, but I know for sure that it was one of the most discussed things in the JSR group (unfortunately, I don't think these debates can be found somewhere so that we can understand the reasoning).

./alex
--
.w( the_mindstorm )p.

Two usage of annotations in AspectJ by Ramnivas Laddad

When annotations are discussed in the context of AOP/AspectJ, it could mean one of the two things.

1. Expressing aspect constructs
The traditional-style (also known as "code style") syntax extends the Java language using new keywords, and consequently requires a new compiler ('ajc'). The @AspectJ-style (also known as "annotation style"), on the other hand, extends the Java language using AspectJ-specific annotations instead of new keyword.

For example, here is a tracing aspect defined using the traditional style syntax.

public aspect TracingAspect {
pointcut trace()
: execution(* banking..*.*(..));

before() : trace() {
System.out.println("Entering " + thisJoinPointStaticPart);
}
}


Here is a functionally-identical aspect defined using the @AspectJ style syntax.

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class TracingAspect {
@Pointcut("execution(* banking..*.*(..))")
void trace() {}

@Before("trace()")
public void log(JoinPoint.StaticPart thisJoinPointStaticPart) {
System.out.println("Entering " + thisJoinPointStaticPart);
}
}

While the above aspect may be compiled using 'javac', you will need to use the AspectJ weaver somewhere between compiling source code and byte code entering the VM. The choices for the weaver are compile-time weaver (use 'ajc' as the compiler), binary weaver (use 'ajc' as the weaver with classes and jar files as input), and load-time weaver (use a classloader or the AspectJ-supplied JVMTI agent as the weaver).

Advantages of the traditional style include compactness of the code and simplified static crosscutting. Advantages of the code style include tool-friendliness (IntelliJ will be happier with the code, since it is Java code from its point of view, and a post-build step can to the binary weaving).

Note that you will need an AspectJ-aware IDE to see the crosscutting reference view (relationship between program elements and aspects). IntelliJ users will not get this functionality easily (there is a standalone tool, 'ajbrowser' and there is 'ajdoc', but the user experience is not the same). Frankly, I am not sure how long IntelliJ can avoid adding the AspectJ support, given increasing use of AspectJ inside and outside the Spring community.

2. Selecting join points
This use of annotations help leveraging the metadata associated with the program constructs in selecting join points. This use is totally independent of the style used to express aspects. For example, you can write a pointcut
execution(@Secure * *(..))
to select all methods that carry a @Secure annotation. I have explored this use of annotation in a two full-length article series (part 1, part 2). The reason to prefer annotations over XML to express metadata is that with annotations it is much easier to write a pointcut to select the required join points.

-Ramnivas

Re: Two usage of annotations in AspectJ by Corby Page

The reason to prefer annotations over XML to express metadata is that with annotations it is much easier to write a pointcut to select the required join points.


You know, I really don't want to get into an AOP argument with Ramnivas Laddad. It's like getting into a drinking contest with Lindsay Lohan. I'm just going to end up looking stupid.

But here is your aspect, your pointcut, and your joinpoints in XML:

<aop:config>
<aop:aspect id="tracingAspect" ref="tracingAspectBean">
<aop:pointcut id="businessService" expression="execution(* banking..*.*(..))"/>
<aop:before pointcut-ref="businessService" method="log"/>
</aop:aspect>
</aop:config>

That was as least as easy and concise as what you did with annotations. And if it wasn't for crappy InfoQ formatting, it would have looked real slick, too.

Now, with XML I can fit all of my aspects on a single page in XML, and have an application-wide view of my architecture. Surely you have to concede that without an AOP-aware development environment this is preferable to dispersing annotations throughout my application.

Re: Two usage of annotations in AspectJ by Corby Page

Ah, here it is nice and pretty:


<aop:config>
<aop:aspect id="tracingAspect" ref="tracingAspectBean">
<aop:pointcut id="businessService" expression="execution(* banking..*.*(..))"/>
<aop:before pointcut-ref="businessService" method="log"/>
</aop:aspect>
</aop:config>


Simlarly, you can do:


<aop:config>
<aop:aspect id="tracingAspect" ref="tracingAspectBean">
<aop:pointcut id="businessService" expression="execution(@Secure * *(..))"/>
<aop:before pointcut-ref="businessService" method="log"/>
</aop:aspect>
</aop:config>


to select all methods that have a @Secure annotation.

Re: Two usage of annotations in AspectJ by Ramnivas Laddad

Corby, you can sure argue with me :-). More importantly, we can sure learn a thing or two from each other.

Let me clarify a bit. When I said, "prefer annotations over XML to express metadata", I was referring to the use of annotations in "Selecting join points" part. The use of XML you are showing belongs to the "Expressing aspect constructs" part.

Tools (as you point), specific project needs, and personal preference direct the choice between traditional, @AspectJ, and XML-based syntax. There are a few fundamental differences between them, though:
1. The traditional syntax needs specific support from tools such as IDE. However, when you do have the right support, you can write concise code and express static crosscutting more directly. Of course, you also get visibility into crosscutting structure (see screenshots in this article, for example).
2. The @AspectJ syntax works reasonably well in environment without specific support for AspectJ (IntelliJ, for example), since such environments can treat the AspectJ code as Java code. It also works great in environments that support AspectJ. For example, in Eclipse you get all the goodies such as crosscutting reference view etc.
3. The XML syntax too works in environment without specific support for AspectJ. It also allows making certain changes to crosscutting functionality without having to recompile. However, a drawback will be (at least with current tools) the lack of visibility into crosscutting structure.

I use the traditional syntax if the team is using Eclipse as the IDE and AspectJ in the fundamental part of the project, @AspectJ in non-Eclipse environments, and XML if quick configuration changes is a requirement (performance monitoring, for example). It is also not uncommon to see use of multiple syntaxes in the same project.

Let me get back to the "prefer annotations over XML to express metadata" point. From AOP's perspective, it is easier to select the required join points when program elements themselves carry annotations instead of putting them in an associated XML file. For example,

@Entity
public class Customer implements Serializable {
@Id Long id;
...

is preferable to

public class Customer implements Serializable {
private Long id;
...

along with

<hibernate>
<class name="com.infoq.domain.Customer" table="customers">
<id name="id" column="ID"/>
...


Just to be sure, I am discussing XML vs. annotation only from AOP's join point selection convenience; there are other reasons to prefer one over other. When program elements themselves carry metadata using annotations, I can leverage that metadata easily in pointcut expressions. For example, I can select my trace points as all methods in domain classes with a pointcut such as execution(* (@Entity *).*(..)) (using traditional, @AspectJ, or XML syntax).

-Ramnivas

Re: Two usage of annotations in AspectJ by Alex Popescu

I use the traditional syntax if the team is using Eclipse as the IDE and AspectJ in the fundamental part of the project, @AspectJ in non-Eclipse environments, and XML if quick configuration changes is a requirement (performance monitoring, for example). It is also not uncommon to see use of multiple syntaxes in the same project.


Excellent summary Ramnivas. IMO, this should be included in the AspectJ FAQ for reference ;-].

Not-so-unrelated: the IntelliJ IDEA 6.0 version will be able to work with Eclipse compiler. I see some new open doors for AspectJ in the future (indeed it is still far, but we've already touched this discussion on the AJ mailing list).

./alex
--
.w( the_mindstorm )p.

Two style of using XML, too by Ramnivas Laddad

I need to add one more point to already lengthy replies!

When we say XML-based syntax, it may mean one of the two things: The AspectJ way of defining concrete subaspects or the Spring way of defining typed advice. It may also mean using pointcut expression while defining proxy beans (but I will not discuss that, since it is quite simple to understand). Most of the generic discussion of XML-based syntax applies to all these styles.

The AspectJ way of defining subaspect targets the use cases that need changes to the selected join points without having to recompile. This is a purposefully limited syntax, where pretty much the only thing you can do is define subaspects and provide a definition for abstract pointcuts in the base aspects. You use aspects defined in this manner with the load-time weaver (although it is theoretically possible that compile-time and binary weaver will understand this syntax as well). Except for the style, there are no semantic differences between aspects defined using XML and using code. Here is an example of aspect defined using AspectJ's XML-based syntax.


<!-- META-INF/aop.xml -->
<aspectj>
<aspects>
<!-- Assume com.aspectivity.monitoring.JDBCMonitoringAspect
is an abstract aspect with an abstract monitoredOps() pointcut -->
<concrete-aspect
name="com.aspectivity.monitoring.JDBCMonitoringAspect"
extends="com.aspectivity.monitoring.MonitoringAspect">
<pointcut name="monitoredOps"
expression="call(* java.sql.*.*(..))"/>
</concrete-aspect>
...
</aspects>
...
</aspectj>


Now if you needed, for example, to monitor execution of methods in banking classes in addition to JDBC, you can simply change the pointcut to the following definition. No need to recompile the classes:

<pointcut name="monitoredOps"
expression="call(* java.sql.*.*(..)) || execution(* banking..*.*(..))"/>


Corby's example is one of Spring's typed advice. This syntax targets the use cases that need to use Spring's proxy-based AOP framework (that does not need a special compiler or load-time weaver). Compared to traditional Spring AOP, this allows expressing (strongly) typed advice i.e. use more specific types instead of Object as the type for the collected join point context. The limitation of this style stems from its use of proxy-based AOP. Specially,
1. You can only crosscut objects managed by Spring. In Corby's example, execution(* banking..*(..)) will select methods matching the expression only for the object created through Spring.
2. You can't use pointcuts such as get(), set(), and handler().
3. You cannot also use execution() or target() pointcut to select constructor execution.

All these syntaxes have pros and cons, with a no clear winner in all situations. This realization is behind AspectJ's and Spring's support for multiple syntaxes and weaving models. A typical developer using Spring framework is expected to first use AspectJ-based pointcut expressions when defining proxy beans in XML, then move on to use typed advice (both using proxy-based AOP and without using any special weaver). Then when he will need stronger AOP support (for fine-grained dependency using @Configurable annotation, among other things), he will use AspectJ.

-Ramnivas

Re: Two style of using XML, too by Corby Page

Thanks, Ramnivas, that's very helpful.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

16 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT