Recently I've been looking into Spring Roo to find ways to speed-up software development as well as reducing plumbing code. In this blog post I will highlight some of the advantages and disadvantages of Spring Roo which I stumbled upon. So don't expect a full featured introduction or tutorial; plenty of those already exist on the internet ;-)
Spring Roo takes on a different approach to code generation compared to other solutions. Instead of generating additional .java files (through the "Generation Gap Pattern") it generates so-called AspectJ inter-type declaration (ITD) .aj source files. Each generated inter-type declaration (ITD) type will "weave in" structural changes to its target .java file; for example to add new methods (i.e. getter/setter methods) or an "implements ..." clause. The big advantages of such inter-type declaration (ITD) are:
- No code-modifications are needed in order to use the generated code (i.e. no need for extending from a generated base class).
- Through "push-in refactoring" in Eclipse one can very easily moving all code from generated ITD .aj sources into its target .java file; when applied on all generated ITD .aj sources all traces (including its annotations) from Spring Roo can be completely removed from the code.
Besides the usage of ITD types Spring Roo takes another different approach. Instead of solely relying on annotations for triggering its code generation it also offers its own command-line shell including full-featured context sensitive help and code completion. For instance JPA entities and their Spring Data JPA repositories can asily be added through only a few very simple commmands in the Roo shell. The following lines are sufficient for setting up JPA support (based on Hibernate + HSQLDB), adding an entity together with its CRUD repository:
jpa setup --provider HIBERNATE --database HYPERSONIC\_PERSISTENT entity jpa --class ~.domain.Pizza --activeRecord false repository jpa --interface ~.repository.PizzaRepository --entity ~.domain.Pizza
These 3 lines of code will:
- Make the relevant changes to the Spring XML configuration and the Maven POM
- Generate 2 .java files: the "Pizza" entity class and its CRUD repository "PizzaRepository". The source code of the generated Java classes is annotated with
@Roo... annotation; For instance the entity class is annotated with @RooJavaBean to trigger the generation of getter / setter methods for each non-transient field (using the AspectJ ITD types).
Actually the AspectJ ITD types for @RooJavaBean (and the other @Roo... annotations) are not actually generated by the 3 lines of Roo shell script. Instead the Roo shell continuously scans for new, modified and delete .java files and modifies the generated .aj files accordingly. The .aj files will not be maintained by Spring Roo unless the Roo shell is activated for your (Maven) module. In my opinion this is a big disavantage since this is error prone:
- Turns out that the SpringToolSuite (STS) doesn't automatically activate the Roo shell after creating a new SpringRoo project in Eclipse (STS)
- Makes it more difficult to generate the .aj files from scratch as part of the Maven build.
As it turns out Spring Roo relies on the obscure "japa" java parser library (http://code.google.com/p/javap...) which turns out to be no longer active (last commits were in November 2011) which doesn't support the Java 7 (and future Java 8) syntax. Instead of choosing "japa" it would have been better if SpringSource would have used a more future proof solution like for instance the Eclipse compiler API. In my opinion it would have been even better if they chosen to use the standardized Java 6 JSR-269 "pluggable annotation processing API"; but as it turns turns out they have chose not in order to support Java 5.
After reading through this blog post one might think I not in favor of using Spring Roo... ... well actually this is not really the case. The Roo shell is a great feature and the generation of AspectJ ITD types is a much better approach than the generation of additional java classes. And... well... the Java 7 support... still a bit of a bummer, but for now not a huge issue. But hopefully when Java 8 arrives Spring Roo will quickly adopts its killer features like closures.