APT

As I mentioned in my last post I’ve been playing around with database interfaces. While doing this, I’ve discovered something new: APT, the annotation processing tool for Java. I’ve known for a while that it existed but only now have I discovered what the big deal is. APT. Kicks. Ass!

In the database interface for Java I’m working on, you specify the structure of a database through annotated interfaces, essentially the same way things work in DLINQ. For instance, a database called test containing two tables would be specified like this:

public @Database("test") interface ITestDatabase extends IDatabase {
public @Table IDataSet public @Table IDataSet orders();
}

Using this interface you can open a connection to an actual relational database and fetch the contents either directly (by calling the persons or orders method) or you can specify more complex queries through something more “magical” which I’ll describe later.

The thing is that there’s a lot of ways you can get these interfaces wrong. For instance, you must use interfaces, not classes. Database interfaces must extends IDatabase. The methods that correspond to tables must return a IDataSet of some sort. And so on.

I considered this to be a problem until I discovered the annotation processor framework. An annotation processor is essentially a compiler plugin that is given access to parts of the syntax tree during compilation. That can be used for all sorts of interesting things, including issuing errors and warnings. So I’ve created an annotation processor that you can plug into your compiler and then it will check that all database-related interfaces are well-formed, and it works beautifully.

To top it all off, the compiler in eclipse now supports APT. If you just configure it correctly, which is no more difficult than using an external library, you get custom checking right in eclipse:

Of course, as with all power tools, you have show a little restraint and not issue all sorts of lame warnings just because you can…

…even if it it’s so easy the code almost writes itself:

for (MethodDeclaration method : decl.getMethods()) {
if (method.getSimpleName().equals("foo")) {
env.getMessager().printError(method.getPosition(),
"Enought with the 'foo' methods already!");
}
]

I know this tool has been around for a while. Why has it taken me so long to discover how useful it is — has there been some kind of hype that I’ve missed?

And yes, I know I’ve misspelled “enough”.

Leave a Reply

Your email address will not be published. Required fields are marked *


*