One of my favourite uses of AspectJ is to generate compile-time error messages. This allows you to provide guidance in the IDE for developers writing new code within a framework or library.
Here’s a quick example. BaseDTO is a base class that developers will extend. It’s used with a framework that requires a no-arg constructor (Jackson in this case, but it’s a common requirement), but when constructed explicitly, the UriInfo parameter is mandatory.
// No-arg constructor for unmarshalling, but otherwise don't call this one public BaseDTO() {} public BaseDTO(UriInfo uriInfo) { this._links = new Links(uriInfo); }
We can’t express that requirement in normal Java. As a result, developers can waste a lot of time debugging a new subclass. AspectJ to the rescue!
public aspect DTOChecker { pointcut dtoConstructor(): call(BaseDTO+.new(..)) && !call(BaseDTO+.new(javax.ws.rs.core.UriInfo, ..)); declare error : dtoConstructor() : "DTOChecker: Constructors for subclasses of BaseDTO must include a UriInfo parameter."; }
Then, if we try to call a constructor for any subclass of BaseDTO without including a parameter of type UriInfo, we get a compile error. In Eclipse, that looks like this: