The Lurker
Java rants: Aspect Oriented Programming
When I stumbled across this blog post about transaction handling in Java the other day, I finally realised what it is about Java AOP that bothers me.
I had previously thought that my AOP skepticism was rooted in the bizarre names for AOP's core concepts ("advice", "pointcut", "join point", "introduction", "weaving") — reasoning that if the idea was any good, better names would have been obvious — or that (after using Bob Lee's dynaop library for about a year on a large project) AOP amounts to a choice between non-standard Java source code and a framework to avoid some of the clumsiness of Java's reflection API when constructing decorators using java.lang.reflect.Proxy
, neither of which appealed to me. Neither impression is a credible argument against AOP; they were attempts to explain my instinct that AOP just didn't feel right.
Euxx refers to a hypothetical code snippet in another blog post by Vincent van Beveren, who would like to see support for clustering in the virtual machine, and persistence in the language:
public persistent class Account { public void transfer(double amount, Account toAccount) !throws AccountException { transaction { try { amount = withdraw(amount, "Transfer to " + toAccount); toAccount.deposit(amount, "Transfer from " + this); Transaction.commit(); } catch (CreditException ce) { Transaction.rollback(); throw ce; } } } }
If I'd written this example, the syntax would be a little different. I would, in general, want commit to be handled by the transaction
construct automatically on normal termination of the block of code, and rollback to be automatic when the block throws an uncaught exception, which would then be re-thrown.
At the moment I'm writing some persistence code at work, where we've written an abstract class that provides this functionality. It would be nice to be able to write code like the above, instead of writing an anonymous inner class extending our helper class inside each method that interacts with the database.
Would be nice, isn't it? Though I think it is not really good idea to put such stuff into the language. Besides, the metadata introduces in Java 5 (and its surrogate JavaDoc-based replacement for earlier JVM's) has been used to implement such features in a more generic way. Basically you could annotate
Account
class with@Perstist
annotation andtransfer()
method with@Transactional
annotation, so infrastructure could use those hints to behave accordingly.
While I agree that Java should make this possible more generically (not by adding one-off "transaction support" to the language, as Charles Miller rightly complained about with the for-each loop), I don't think annotations and "infrastructure" — Euxx goes on to explain that this probably means one of the existing AOP frameworks, such as AspectWerkz or AspectJ
— have anything to do with it.
It seems pretty clear to me now that the right solution here is a macro system, transforming code like the above into concrete Java code at compilation time. If I could change one thing about Java, it would be to add a macro system. (Well, either that or add the post-assignment operator.)
All timestamps are Melbourne time.