« February 2006 | Main | April 2006 »

March 10, 2006

Graham Hamilton on AOP

Graham Hamilton posted a blog entry on AOP this week. It's attracted a good deal of criticism in the responding comments - probably because of the provocative writing style. Graham's certainly been in the game long enough to know the difference between technical discussion and political positioning - and how to blur the two. Graham divides his criticism into "the good", "the bad" and "the new". "The good" includes container based AOP, "the bad" includes just about everything else. "The new" is apparently annotations. Comments on Graham's blog can't be linked directly - but crazybob and "bigcheeese" do a good job of setting the record straight there. In short, Annotations != AOP, but annotations can certainly facilitate AOP (see Ramnivas' articles AOP and metadata: A perfect match, Part 1 and Part 2 for a much more detailed analysis.

So... let's take a step back here. Graham is positioning for container-based "AOP", which he appears to interpret as use of annotations that your container understands, in order to provide interception. Hmmm. What annotation-based container have Sun been working on recently I wonder? EJB 3 perhaps?? I predict that Graham will soon be telling us that Sun have solved all of our AOP needs within the safety of the JSR process, and all we need is EJB 3 with its @AroundInvoke and friends. Sorry Graham, @AroundInvoke != AOP either, by a very long chalk.

If you want container-based AOP, check out Spring AOP. What we had in Spring 1.x was way ahead of any @AroundInvoke style mechanism. What we've got in Spring 2.0 is two generations of technology ahead, and quite simply the best container based AOP there is (IMHO of course). I'll be talking about some of this in my TSS Java Symposium presentation later this month for those who are interested and will be in Vegas.

In "the bad" Graham takes a line of argument that "side files" and "runtime mechanisms" modify the semantics of the JLS. "Arbitrary intervention" with "arbitrary side effects" is a "quick race across the boundary line to insanity". Provocative wording indeed. AspectJ is a language. It's program constructs have semantics. There is no "arbitrary intervention" or "arbitrary side effect". The "side files" are source files written in the AspectJ language (it's kind-of normal for a language to have source files). AspectJ does support load-time weaving, which can link aspects with compiled classes at load time, but this has exactly the same well-defined semantics as the most common way of using AspectJ: compiling source files using a compiler that honours the semantics of the language by translating source code into a lower-level representation that is then interpreted by the JVM. If Graham doesn't like that idea, I guess he doesn't like javac either?? I think the underlying point that Graham was really trying to make underneath all the sensationalist language is the oft-heard assertion that aspect-oriented programs make it harder to understand what the program does. See the developerWorks article AOP myths and realities for a response to that point. Readers should also check out Gregor Kiczales' comment on Graham's blog. The truth is, as Wes Isberg recently reminded me "it's *all* an illusion anyway. Even the beloved JLS semantics.

Any technology, any language, can be used in an inappropriate manner and thus cause problems. The question is, does a technology or language make it easy to do the right thing, and in so doing give benefit to its users? I thought I'd let some of the posters to TSS over the last month have the last word on this...

On JBoss Cache:

JBossCache is a good example. We use AOP to implement the following cross-cutting concerns:
- Locking, depending on whether we use pessimistic or
  optimistic, we use a different interceptor
- Replication. If the cache is local, the
  ReplicationInterceptor is not present
- Invalidation. simply replace the ReplicationInterceptor with
  an InvalidationInterceptor (of course all interceptors are
  assembled by the cache at startup time, this does not have
  to be done by the user)
- Cache loading and cache storing
- Statistics. If disabled, the interceptor is not present
- Transactions

We even open the chain of interceptors up, so devs can insert their own
 (auditing, security etc).

The first version of JBossCache did *not* use AOP, and it became hard to maintain code that 
have to cover all permutations of 'aspects', e.g.
- transactional asynchronously replicated cache
- non-transactional local cache
- non-transactional synchronously replicated cache
etc etc etc

We already reaped the benefits of the refactoring: when we added optimistic locking, 
we simply replaced 1 interceptor.
JBossCache would today be unmaintainable without AOP.

On AOP in enterprise systems:

I've used AOP for several functions in enterprise systems:

- performance monitoring 
(see http://www.ibm.com/developerworks/java/library/j-aopwork10/ for my article 
that shows how this works in detail)
- macros & user feedback in a rich client app
- fine-grained (data-level) authorization
- error handling (isolating, summarizing, and consistently responding to errors)
- testing

In each case, AOP let us write clean code that's noninvasive and separately testable. 
By contrast, if we had scattered and tangled the implementation of these requirements 
it would have been virtually impossible to be consistent and correct. I think the AOP solution
is far preferable to the code generation, boilerplate templates, and heavyweight, and 
inflexible frameworks that people traditionally reach for to cope with these kinds of problems.

On reuse across projects:

> No AOP is only good for logging and tracing. Its a techy toy that will cause serious
> trouble and should be banned from any enterprise environment because of the 
> maintainance issues it will undoubtedly create down the line.Show a good example 
> where we would really use it

Wrong on all counts. We use it for
   Security
   Profiling
   Caching
   Transactions
   and soon
   Messaging
   Unified exception handling.

As usual, the only people who seem to berate never actually used it.

Oh, I almost forgot, all those items are reused across currently six different projects and 
NONE affects the business logic.

On the learning curve::

I have the opposite experience. AOP terminologies and syntax many feel strange initially
 (as is the case with any interesting technology). However, in my experience, most 
developers understand them quite easily.

I present AOP/AspectJ at many No Fluff Just Stuff and other conferences. I have a pretty 
uniform experience that most attendees understand the power, concepts, and syntax 
fairly well. For example, after explaining a few simple pointcuts, I ask attendees to tell 
me syntax for more complex pointcuts. I am happy to report near 100% correct answers. 
To me, this is an indication that the syntax is logical and predictable.

The same experience is repeated with developers at client sites. Developers understand 
the concepts and syntax very quickly (perhaps because they are motivated by its potential
to solve the problems they are facing!). Granted, many don’t understand the full power and
implications of using AOP right after the first introduction, but that isn’t unexpected.
As the article explains, it does take time to fully fathom AOP, much like any other technology.

A new user::

I actually just started using it.

We have a fairly large object model, used by (right now) two very distinct applications.
Due to certain realities, one project needs to listen to certain properties and the other 
project doesn't. I used AspectJ (AJDT in Eclipse) to instrument the model with the proper
interfaces, defined the proper pointcut, and it's working beautifully.

Took ~ 1 day to get used to the 'new' terms. Took another to get used to the syntax. 
Now the property change stuff is used only by the app which needs it, with absolutely 
zero impact on the other app.

Reality check::

We have been using AOP as the foundation for our CMS/portal products for three years now. 
It's working great, we don't even use it for logging and tracing at all, and some of the 
stuff we do would be impossible without AOP, not because they could not be coded, 
but because they would be horrendously expensive to write and maintain.

We use it for asynchronous event handling, undo management (on the client), 
replication, transactions, security, caching, parameter validation, the entire object model
(in a way that would be more or less impossible to do without AOP), versioning of state, 
automatic persistence, locking, last modified timestamps, business rules, client/server 
synchronization, and lots lots more.

In other words, it is not "only good for logging and tracing", it is not a "techy toy", and 
it should most definitely not be "banned from any enterprise environment".

There are other things that definitely should be banned from enterprise environments 
though, such as yacking about things that one knows nothing about. Now, there's 
something that'll cause all kinds of problems down the line.

On the cost of implementation:

All good suggestions!

I have used AOP in pretty much all the scenarios you mention. In all cases, I found that 
the cost of implementation is reduced significantly. Often, many useful features that 
would not have been implemented due to sheer implementation complexity associated 
with them (automatic fail over logic, for example) become suddenly very attractive when
 implemented using AOP.

For the client side, I have seen Swing thread safety aspects saved the day for quite 
a few projects.

Some specific projects/products for the ideas you mentioned implemented using AOP: 
Audit trail: see: http://nearinfinity.com/products.html
Monitoring: http://www.glassbox.com/glassbox/Downloads.do 
(and http://www.ibm.com/developerworks/java/library/j-aopwork10)
<plug>
For authentication and authorization implemented using AspectJ, check out chapters 
from my book  (free download): http://manning.com/books/laddad/chapters. 
Also take a look at table of content for a range of problems solved with AOP.
</plug>

The bottom line is a quote from the article: "...the only way to find out whether 
AOP is a good addition to your development practice is to try it for yourself.
I suggest that you set aside one full day to experiment with AOP -- not by 
reading articles, books, or blogs, but by coding aspects for yourself. 
Doing that will let you form your own opinion of AOP, which ultimately is what 
really matters."

On AOP helping to keep the Java platform competitive:

The team that I am working with now created a framework based on Facelets, 
AOP (heavy use of AOP, AspectJ and Spring AOP), JSF, Spring and Hibernate. We can 
create a simple database web application in a fraction of the time it use to take with 
a fraction of the code. It is all Java based. We are in the process of getting permission
to write a white paper. This framework has built in support for 
pagination, filtering, etc. etc. And, you can augment with standard JSF, and Java. 
(Like RoR this framework is not for Amazon.com, but it fits a lot of web application 
nicely). Also since we are built on top of Hibernate we can easily add caching. 
Since we are using AOP, we can easily add just about anything really (IMHO).

If you have your own success stories with AOP, I'd love to hear them. If you tried AOP and it didn't work out for you, I'd love to hear about that too so that we can learn where we need to do better...

Posted by adrian at 01:44 PM [permalink] | Comments (2)