Real-world Spring Roo. Part 2 – Aspects and what this means to us

Despite of the fact that Spring Roo and Grails share the same concepts and use pretty much the same libraries underneath – these are written in two different languages: Java for Roo and Groovy for Grails. The static vs dynamic nature of the language is a major difference since what you can do in Groovy with meta programming can be hardly done with Java. This is especially visible in DAO layer where you don’t get the same level of flexibility in Roo like you get in GORM.AspectJ and to auto-generation during development are used to make things close to GORM but in Java. Lets have a look at Version DAO class :

Pretty much each annotation causes generation of the separate AspectJ file in the development phase. For example @RooJavaBean will generate:

And this happens for each annotation:

  1.  @RooToString generates the default toString implementation (Version_Roo_ToString.aj) based on ReflectionToStringBuilder from Apache commons-lang
  2. @RooJson generates Version_Roo_Json.aj aspect which provides a way to convert your objects to JSON and vice versa with the help of flexjson.
  3. @RooJpaActiveRecord generates Version_Roo_Jpa_Entity.aj with the two required fields id/version and getters/setters. id a surrogate primary key and version is used for optimistic locking. Another interesting aspect file is Version_Roo_Jpa_ActiveRecord.aj. This file provides an ActiveRecord pattern functionality for the entity. It contains persist/merge/remove/findAll/count/findEntries methods which are really convenient.

You shouldn’t make changes in the generated files manually since these will be overwritten. The only time the editing of aspect files makes sense is when you move the method generated out of it to override.

So what’s not really convenient about aspects?

To generate these invisibly you need some support from your IDE. It’s a bit painful to regenerate these if you get used to vim. This also limits a set of IDEs you could use. NetBeans does not have AspectJ support at all and won’t have in future. I think IntelliJ IDEA support is really good but I prefer not to use this IDE. So the only reasonable choice for me is Eclipse-based STS from SpringSource with AJDT plugin installed. It does everything you need.

The aspects in Roo also have some limitations.

Lets start from @RooJpaActiveRecord:

  1. We’re not able to specify the default sorting in @RooJpaActiveRecord. It’s a usual functionality: to provide some reasonable default sort order in your grid. But to do this you need to implement your own query and method.
  2. To build queries you can use a thing called finders. You can generate the query from name. You just need add something like findVersionsByNameLikeOrDescLike in the Roo Shell. Still way to add ordering here also.
  3. There’s no way to generate count query for finders. It could really useful for pagination
  4. The code which is generated for the finder is highly self-repeatable. Once you need to override some aspects of this code – you’re to copy and refactor this horror.

@RooJson also has some problems:

  1. There is no way to prevent serialization of the field in the declarative manner. You can’t just put @Transient annotation and expect that the field will be skipped during serialization. You need to override methods and add you own explicit exclusion.
  2. Serialization of hierarchies is a sort of a pain if you need to exclude a field in some inner object.It’s really painful if you have multiple outer classes referencing this object. You need to add exclusion into each upper-class to prevent this field from being serialized.
  3. FlexJson used for serialization works in non-strict mode. It uses read  properties to get data and silently skips the attributes which it doesn’t know how to deserialize. As a result in case of using some pseudo-properties you can get a situation when your JSON read/write is broken trying to parse data with same classes but a different library like jackson.

This was description of the limitations in the usual CRUD applications. However you get lots of things without any development. Hopefully I’ll find some time this year to help fixing these limitations.