Spring “Roo” is the latest to come out of the SpringSource stable. Since the same stable houses some stalwarts like Spring framework and Grails, I was keen to see what this animal was all about.
About the name “Roo” – sounds to me like it has something to do with an Australian marsupial …
So what is Roo? Roo is not a new library, it is not a framework, it is not an IDE, it is not a build management tool; yet it is something of all this. Roo is marketed as a “next-generation rapid application development tool for Java developers”. In simpler terms, what Rails is to Ruby, Grails is to Groovy, Roo is trying to be the one for Java.
In keeping with the tradition started by Ruby (?), Roo also runs out of a command prompt/shell. The shell has features like auto-complete (using Tab key), hints and help.
“The ten-minute tutorial” in Roo’s site is a good starting point. For people too lazy to try that out, here is the gist of the story. (I will skip the part where you download latest roo zip and set up the path)
Step 1: Open your console. Type “roo” – depending on your OS, most probably you will end up with a green highlighted screen which screams “ROO”. Now you are in roo shell. If you keep on typing “hint”, Roo will walk you through the basic steps of setting up an application.
We will fast-forward through the commands first and try to explain what happened.
$roo roo> project --topLevelPackage com.tenminutes roo> persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY roo> entity --class ~.Timer --testAutomatically roo> field string --fieldName message --notNull roo> controller all --package ~.web roo> selenium test --controller ~.web.TimerController roo> perform tests roo> perform package roo> perform eclipse roo> quit $ mvn tomcat:run
What we have done with these steps is to
Step 2: Create a project
Step 3: Set JPA provider as hibernate and database as Hypersonic (In memory)
Now Roo guys believe in “Domain Driven Design (DDD)”. So you start your application designing your domain objects. Hence,
Step 4: Create a JPA entity called Timer and provide it auto generated test classes (more on this later)
Step 5: Add a field to the entity called message, type String, and it’s non-nullable.
Yes! You have the option to add these fields either from the command prompt or from a text editor. Roo will not mind. But before you right-click and do a create getters and setters in your favorite IDE, listen!
*Roo provides round-tripping*
That is whenever you change something in your code; Roo will keep on updating all its productivity-improving-auto-generated-stuff, so long as you keep the console running. Even if you kill the console, open an IDE and do all sorts of changes to your Java class (your entity Timer in this case), as soon as you open the console and go to the current project, Roo will find out all that you did behind its back and will update its own records accordingly. Speaking of records, Roo maintains a metadata of all the classes it manages. That is how it tracks all this.
Another question at this point could be, how does Roo manage to keep the code you wrote and the code it generates separately? Good question!
*Roo uses ITDs*
That is the secret sauce to most of what Roo does. IT-what? ITDs or inter-type-declarations are all about AspectJ and its version of AOP. Anyone who has worked with Spring before may recognize AOP and Spring’s preference to AspectJ’s implementation of AOP. If you have never heard of AOP before, please don’t be impatient. By the time I am done explaining how ITDs work, you will probably understand something. If you are still clueless, I will add some good references at the end.
OK back to ITDs. Whenever you create an entity, Roo improves your productivity by generating all the template code that you would have had to write otherwise.
As an example, it creates all the getter and setter methods (accessors and mutators). It also creates a decent toString implementation. It then injects its own JPA EntityManager and creates all the CRUD methods for you. It even throws in @Transactional annotation for you.
But if you look into your Timer class (~.Timer means .Timer) using an editor, you won’t see any of these. Unless you played around with the class, all you will see is the “private String message” field. However if you look around in the package, you will see some .aj files floating around. These are AspectJ ITD files. If you open them you will see Java like code inside them with all the methods I mentioned. That is how Roo seperates its code from your code. You can go on editing your own .java class, Roo will not mind, its stuff is inside the .aj files. OK, now how do you get to use these non-java files in your application?
At compile time, what is known as “compile-time weaving” happens. (ITDs are also called “mixins”, it seems). At the end of your compilation cycle, the resultant .class files will be a “mix” of your Java code and Roos’ generated code. So the code that you deploy, will never know that it existed in its previous life in multiple files.
The only hitch here is that if you like working with an IDE like eclipse; you may have trouble getting auto-completion of methods. After all most of the methods are outside you .java file. Also you may see those ugly red markers if you type in the method anyway. Good news is that if this happens to you, you are in an older version of eclipse. New versions of eclipse (3.3+ i think) support AspectJ. So you will directly get auto-completion blah-blah.
Now that we have seen the major behind-the-scene story if Roo, let us go back to our 12 step program. So you have typed in your entity fields and Roo does everything else for you.
Step 6: Create the Controller classes in a package com.tenminutes.web.
Roo’s default application framework consists of Spring MVC at the front and JPA entities at the back. Nothing else! No DAO/Repository, Service nonsense.
Pure REST based DDD applications. (Shocked? we will discuss this also later)
In this step we created MVC Controller classes for the entities. These are scaffolded Controllers. Again you end up with almost empty Java classes. All standard REST based methods are auto implemented for you. These directly talk to your Domain entities and get things done. You will also get JSP pages from where these can be invoked.
By this step, you have completely developed a full-fledged killer app with which you will make your millions.
Step 7: You create selenium test cases for your auto create pages.
Next two steps show what is under the hood. Internally Roo uses maven(v2) to set up the project, download all the dependencies and manage the build. (There is a ticket in the Jira to support Ant+Ivy)
With these steps, it runs the Unit tests (yes, they were also created for you … as I promised I will come back to this) and packages your war for you.
Step 10 is optional. If you are would like to import your project into eclipse IDE, Roo again leverages maven to create the .settings and .project files for you.
Now you are ready to quit from the Roo shell. From outside the console, you can type your last command, which is to run the built-in tomcat server to see your application in action!
I hope by now you have got a fairly good idea of what you are stepping into, when you opt for roo.
Roo and Flexibility
With Roo you always have the option to say, I don’t need Roo anymore. What I mean is that, there is no Roo dependency anywhere in your project. There is no Roo library jar, Roo container, Roo servlet or anything like that. The application generated uses your regular Spring, Spring MVC and JPA. The default JPA providers given are Hibernate, OpenJPA and EclipseLink. But that doesn’t stop you from modifying the persistence.xml and spring configuration file to switch to Toplink. You may also want to modify the maven build file (pom.xml) to download toplink jars for you. That is the kind of flexibility we have.
If you want to stop using Roo, perhaps you may want to get rid of the separate .aj files. For this currently you will have to use Spring’s STS (eclipse based) IDE which is free. It has options to merge the .aj files into your .java files. After that no one will know that you ever used Roo.
Roo and Unit Testing
About Unit Testing (which I have been putting off …)
Roo generates Integration test classes as well as regular Unit test classes. For the integration tests, Roo even provides mock data using its “Data on Demand” (dod) feature.
I am personally not completely satisfied with this feature though. The DoD test data is incomplete. For example it does not take care of most of the constraints placed on the entity fields like maxlength for the test data. There is a bug reported on this in Jira, currently its priority is low. I saw in the community that the leads are not recommending DoD for complex entities.
Another issue I had with DoD was its poor support for @OneToOne mapped entities. It doesn’t generate a one-to-one mapped entity in the mocked entity. If this mapped entity is set as required (optional=false), then your test case fails! Not because of your problem, but because Roo can’t do it right!! (UPDATE: Roo 1.0.2.RELEASE has a fix for OneToOne DoD, I am yet to test it)
All in all, my take on Unit testing feature is that, it “gives” you (&the client) the “impression” that it is Test driven development – the maven build will even tell you that all your tests have passed.
But in reality, you should write your own “real” test classes at the end of the day.
- Roo supports JSR303-Bean validation. So you can put annotation based validations in your entity fields. This provides you business level data validation.
- Even though the default architecture does away with Service and DAO/Repository, you can still write your service classes if warranted. Use Spring’s @Service annotation so that Roo identifies it. Also you can use Spring’s @Repository and create Daos. However since all the job done by conventional DAOs is encapsulated either in your entity or the .aj files, you really may not need it.
- Roo also helps you see all the JPA finder methods (like findTimerById(Long id)) and you can chose the ones you need. You use the commands “show finders” and “add finder” to do this.
- Roo not only creates its own Controllers. Roo will help you create your Controller classes also (without any AspectJ magic attached).
- Spring security is provided as an addon. A single command setsup a default configuration. You can modify this and use on your own.
- Ditto for Log4j, JMS and Email.
Conclusion or My Personal Opinion
What I feel is that we need to wait a bit more till we can use Roo actively in project development. Users have only started using it (version 1 GA was released in Dec 2009). The feedback is coming in and more features are getting added. So if we wait a bit more, we will have a bit more matured Roo.
I am also sceptical about the scaffolding feature of these types of frameworks. In my experience 99% you have predefined UI to support. Maybe for quick prototyping it is useful.
The greatest advantage I see is that it takes care of setting up a JPA based Spring application for you based on the best Spring recommendations. (Spring MVC is optional). You don’t have to read through the spec and try to find the best solutions available (Springframework documentation has become huge of late with multiple options to do the same thing). Also it takes care of downloading and setting up your jar files (thanks to Maven). Due to this maven connection it can also be called a build time tool. You can directly use Maven if you so wish (maven pom files are set up for you). So integration with CI tools should be easy.
The DDD and test support are also welcome. The same applies to small departmental applications to large enterprise scale application development.
2. http://blog.springsource.com/2009/05/01/roo-part-1/ (see part 2 and part 3 also)