Introducing Spring ROO: Part 1

Over the past few months I have been involved in the development of a new Spring project codenamed ROO. Spring ROO provides interactive, lightweight, user customisable tooling that enables rapid delivery of high performance enterprise Java applications. If you want more information about the purpose, intended target audience and capabilities of Spring ROO you can take a look at the summary provided at springsource.org/roo.

Currently, you can vote on the final name of Spring ROO on a website that was developed entirely using ROO itself during the SpringOne Europe 2009 opening keynote. The voting Web site is available here: http://cloud.springsource.com/vote

Spring ROO requires you to have Apache Maven version 2.0.9 or higher installed.

A first binary release of Spring Roo is now available.

[Update: the download location for Spring ROO has been moved to http://dist.springframework.org/milestone/ROO/spring-roo-1.0.0.A1.zip]

The complete package of Spring ROO is just 2.7 MB so you should be up and running in no time. To install, simply unzip the package, and create a ‘ROO_HOME’ system environment variable and add %ROO_HOME%/bin to your path. More info in the readme.txt file included in the release. Also, until the ROO annotations jar archive is available in the maven repositories you need to install it manually into your local Maven repository:

mvn install:install-file -DgroupId=org.springframework.roo \
  -DartifactId=roo-annotations -Dversion=1.0.0.A1 -Dpackaging=jar \
  -Dfile=$ROO_HOME/dist/roo-annotations-1.0.0.A1.jar

If you want to import ROO generated projects into Eclipse you should also have the latest AJDT dev build installed. To do this simply use the following AJDT URL in the Eclipse update manager: http://download.eclipse.org/tools/ajdt/34/dev/update.

Once these installation steps are behind you the fun can start. First you should create a new directory to start your first ROO project. Once you are in that new directory simply type ‘roo’ to start the shell (note, if you are not using linux you will miss out on the cool colouring scheme used in the Spring ROO shell:

  • ROO Shell

However, tab completion works just fine in all shells we tested so far.

Now let’s start with a simple application. For this introduction I have chosen to write a simple shopping list containing only ShoppingList and Item as domain objects. Before we get to the details of how to generate classes using Spring ROO we should create a simple project which has all the required artifacts configured. Before you start copy and pasting the commands below into the ROO shell, just try to use the shell directly by using the tab completion feature. So to type the first command below you could type ‘cr’ + + + net.stsmedia.roo.shoppinglist.

create project -topLevelPackage net.stsmedia.roo.shoppinglist
install jpa -database HYPERSONIC_IN_MEMORY -provider HIBERNATE
configure logging -level DEBUG

This will not only create a simple project (using common Maven project structure conventions), but also configure the JPA artifacts in the appropriate places in the applicationContext.xml and the META-INF/persistence.xml files. Finally, since I am keen to see if everything works I am also configuring DEBUG level logging for my project.

Now on to the more interesting parts of this little exercise. I need to create my domain objects for the shopping list application:

new persistent class jpa -name ~.domain.Item
add field string -fieldName name -notNull
add field string comments -sizeMax 150
add field number -fieldName price -type java.lang.Float

new persistent class jpa -name ~.domain.ShoppingList
add field string -fieldName title -notNull
add field date jpa -fieldName shoppingDate -type java.util.Date
add field set jpa -element ~.domain.Item -fieldName items

As you can see we have created the two domain objects Item and ShoppingList and we have added some fields to these objects. The optional command attributes -notNull and -sizeMax directly translate into JSR 303 Bean Validation annotations which I have introduced in my previous post. At the same time ROO analyses these annotations and creates some Dojo code which enables Browser based validation. Further, the domain objects are validated in the Spring MVC controllers and if errors are found, the respective fields are marked accordingly even if JavaScript support is switched off in the Browser.

You may have also noticed that there is no need to define identifier and version fields as ROO takes care of that for you. However, custom identifiers are also supported.

Something we need to do in future though is to provide some support for default messages.properties which translate the sometimes pretty cryptic messages generated by the Spring MVC binding framework and the Bean Validation API into a more human readable format.

Anyway, back to our sample application.

new controller automatic -name ~.web.ShoppingListController
new controller automatic -name ~.web.ItemController -formBackingObject ~.domain.Item

Two things I should mention about the commands shown above.

First, you may have noticed I used the ‘~.’ syntax in front of the sub-package name ‘web’. The ‘~’ character indicates to use the fully qualified package name ‘net.stsmedia.roo.shoppinglist’ we have used in the very first command shown above. Alternatively, you could have used the fully qualified package name directly ‘net.stsmedia.roo.shoppinglist.web.ItemController’ (tab completion gets you there even faster – just try it out!).

Second, you may wonder why the first controller does not have a formBackingObject defined. In fact, ROO does add the form backing object by itself. It does this by remembering the last class file you edited (which was the ShoppingList object as seen above). So ItemController needs a formBackingObject defined, otherwise ROO would assume ShoppingList as the form backing object for Item.

Now, all you are left to do is to ‘exit’ the ROO shell and type ‘mvn install’ to generate a ready-to-deploy war archive. Alternatively you can type ‘mvn eclipse:eclipse’ to generate the Eclipse project artifacts and import the project into Eclipse. If you do so you need to enable AJDTs AspectJ weaving so that the ROO generated aspects can be woven into your binary class files.

After deploying your application to a Web container you can navigate to http://localhost:8080/shoppinglist/:

  • Roo Shell

So there you have it – with only 11 (tab assisted) commands I have created a fully working Web Shopping List application which uses Spring 3.0 @MVC REST features, JPA, AspectJ mixins, and Dojo.

Finally, let’s take a quick look at some of the generated code:

@Entity
@RooEntity
@RooJavaBean
@RooToString
public class Item {

    @NotNull
    private String name;

    @Size(max = 150)
    private String comments;

    private Float price;
}
@Entity
@RooEntity
@RooJavaBean
@RooToString
public class ShoppingList {

    @NotNull
    private String title;

    @Temporal(TemporalType.TIMESTAMP)
    private Date shoppingDate;

    @OneToMany(cascade = CascadeType.ALL)
    private Set<Item> items = new HashSet<Item>();
}
@RooWebScaffold(automaticallyMaintainView = true, formBackingObject = ShoppingList.class)
@RequestMapping("/shoppinglist/**")
@Controller
public class ShoppingListController {
}

As you can see, there are only annotated classes and fields in the generated .java source files. You may wonder where the actual code resides. For this you can take a look at the .aj source files which contain the identifier fields, the mutators and accessors for these fields, and a number of other things. But that is for another post :-) .

We are interested in feedback from you, so please feel free to leave a message!

  • Share/Bookmark

40 Responses Subscribe to comments


  1. Keith Thomas

    Given that Grails already exists in the space I’d be interested to know why ROO is significant and worth my time to take a look.

    Apr 29, 2009 @ 03:32


  2. Marcel Overdijk

    I’m questioning myself the same…

    I think SpringSource needs to come up with a statement on this. It’s confusing.

    Cheers,
    Marcel

    Apr 29, 2009 @ 05:26


  3. Joost

    ROO is extreemly cool. Aparently both previous commenters haven’t been to the SpringOne. ROO is an extreemly powerfull tool to quickly generate lots of stuff which is always standard and takes a lot of time to make and maintain.
    Can’t wait till the next release (2 weeks) so I can start making my own addons.

    Apr 29, 2009 @ 08:10


  4. Joost

    Seems like you need JDK 6 to run ROO. Get an NoSuchMethodException for java.util.ResourceBundle.containsKey(String).

    Apr 29, 2009 @ 08:28


  5. roger

    So this is like the Springource version of appfuse?

    Apr 29, 2009 @ 10:16


  6. sschmidt

    @Keith & @Marcel,

    We found there was a high interest in having a productivity solution which helps getting started and managing Spring applications. This is partly because many people don’t want to move to Groovy or the use of dynamic languages is currently not approved for use in their enterprise applications. Others want static typing and generally like to stick with Java-based applications.

    So Groovy, Grails, Roo and other solutions all have their own pros and cons. Ideally, you should take a look at as many of these solutions as you can and then decide which one suits your individual requirements or perferences most.

    Stefan

    Apr 29, 2009 @ 12:10


  7. sschmidt

    @Joost,

    Thanks for your interest and enthusiasm for ROO :) .

    Yes, ROO currently requires Java 6 which seems reasonable given that Java 5 is in the middle of its EOL cycle (ending Oct 2009). However, code emitted should be ninary compatible with Java 5.

    Once we have the public Jira setup you can provide some more feedback on this in case you have specific requests.

    -Stefan

    Apr 29, 2009 @ 12:15


  8. sschmidt

    @Roger,

    Spring ROO takes a different approach in its core concepts compared to AppFuse. ROO has extensive use of metadata for management and it embraces AspectJ mixins on a new level among other things. We are planning to provide some more details soon.

    Source code should be made available within a short period of time as well in the first milestone release.

    In the meantime I encourage you to try it out and take a look at the results.

    Apr 29, 2009 @ 12:20


  9. Jules

    It looks like you’re using Spring MVC. Does ROO work with Spring Web Flow?

    thanks

    Apr 29, 2009 @ 13:35


  10. Keith Thomas

    @Stefan

    Thank you for your candid answer.

    My own personal opinion is that the Java developers who do not move onto more time efficient JVM languages, like Groovy, are similar to those who in the past chose to remain as Cobol programmers. i.e. they will find plenty of sustaining work but very little new, interesting work.

    I wish you luck as I am fascinated to see if you can succeed with your new framework when your target market is those most resistant to change.

    Apr 30, 2009 @ 11:06


  11. Jim

    Followed your directions. Cut/paste the code and deployed to Tomcat 6. Got this error:

    Returning eagerly cached instance of singleton bean ‘entityManagerFactory’ that
    is not fully initialized yet – a consequence of a circular reference
    BeanConfigurerSupport failed to create target bean ‘entityManagerFactory’ while
    configuring object of type [net.stsmedia.roo.shoppinglist.domain.ShoppingList] (
    probably due to a circular reference). Proceeding without injection.

    [Edit: cutting off the stack trace slightly to make comments more readable]

    May 01, 2009 @ 00:07


  12. rhart

    I’ve downloaded the alpha code, run the vote.roo script and when running the unit tests get a null pointer exception. Does anyone else get this problem?? It looks like the entityManager is null

    May 01, 2009 @ 19:26


  13. rhart

    I also tried the above example and when deploying to Tomcat 6 get the following error

    BeanConfigurerSupport failed to create target bean ‘entityManagerFactory’ while configuring object of type [com.capgemini.shoppinglist.domain.ShoppingList] (probably due to a circular reference). Proceeding without injection.
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘com.capgemini.shoppinglist.domain.ShoppingList’: Injection of persistence fields failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘entityManagerFactory’: FactoryBean which is currently in creation returned null from getObject

    [Edit: cutting off the stack trace slightly to make comments more readable]

    May 01, 2009 @ 19:56


  14. sschmidt

    Hi guys,

    Sorry for the delayed response. I am in the process of moving house and managed to crack my back along the way :) .

    The circular reference problem both of you see is a known issue that happens during the application context initialization (which is also done during the tests).

    This should not have any negative impact on the tests or the running of the application after it is initialized. So the tests should pass and the application should run just fine.

    Do you actually have problems running the applications?

    May 01, 2009 @ 21:57


  15. Jules

    The application does not function. After getting the error during deployment (posted earlier), I able to bring up the main page fine. But once I try to create a new item, this exception is thrown:

    Using EntityManagerFactory ‘entityManagerFactory’ for OpenEntityManagerInViewFilter
    Returning cached instance of singleton bean ‘entityManagerFactory’
    Opening JPA EntityManager in OpenEntityManagerInViewFilter
    DispatcherServlet with name ‘shoppinglist’ determining Last-Modified value for [/shoppinglist/item/form]
    Mapping [/item/form] to handler ‘net.stsmedia.roo.shoppinglist.web.ItemController@5d4177f3′
    Last-Modified value for [/shoppinglist/item/form] is: -1
    DispatcherServlet with name ‘shoppinglist’ processing GET request for [/shoppinglist/item/form]
    Resolving exception from handler [net.stsmedia.roo.shoppinglist.web.ItemController@5d4177f3]: org.springframework.beans.TypeMismatchException: Failed to convert value of type

    [/java] to required type [java language=.lang.Long]

    ; nested exception is java.lang.NumberFormatException: For input string: “form”
    Resolving to view ‘uncaughtException’ for exception of type [org.springframework.beans.TypeMismatchException], based on exception mapping [.lang.Exception]
    Exposing Exception as model attribute ‘exception’
    Handler execution resulted in exception – forwarding to resolved error view: ModelAndView: reference to view with name ‘uncaughtException’; model is {exception=org.springframework.beans.TypeMismatchException: Failed to convert value of type

    [/java] to required type [java language=.lang.Long]

    ; nested exception is java.lang.NumberFormatException: For input string: “form”}
    org.springframework.beans.TypeMismatchException: Failed to convert value of type

    [/java] to required type [java language=.lang.Long]

    ; nested exception is java.lang.NumberFormatException: For input string: “form”

    [Edit: cutting off the stack trace slightly to make comments more readable]

    I’ve heard some positive feedback on ROO and would like to test it farther. But, right now, I can’t get past the errors…

    May 02, 2009 @ 00:45


  16. rhart

    I dont get quite the same as Jules I get

    org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public java.lang.String com.capgemini.shoppinglist.web.ItemController.create(com.capgemini.shoppinglist.domain.Item,org.springframework.validation.BindingResult)]; nested exception is java.lang.IllegalStateException: Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?) at

    [Edit: cutting off the stack trace slightly to make comments more readable]

    Looks like problems with my Entity Manager being injected???

    p.s good luck with the move, from my experience you’ll need it :-)

    May 02, 2009 @ 03:13


  17. Jules

    I tried running the petclinic sample application. it loads fine in eclipse. this error is thrown when i hit link ‘list all pet types’. if i try to create a new pet type, i get the same ‘failed to convert value String to required type Long’ error which I posted earlier. deployment of petclinic is fine (no problems).

    jdk 1.6.0_13 64 Bit
    tomcat 6.0.10
    eclipse 3.4

    INFO: Starting Coyote HTTP/1.1 on http-8087
    May 1, 2009 11:50:34 AM org.apache.jk.common.ChannelSocket init
    INFO: JK: ajp13 listening on /0.0.0.0:8009
    May 1, 2009 11:50:34 AM org.apache.jk.server.JkMain start
    INFO: Jk running ID=0 time=0/69 config=null
    May 1, 2009 11:50:34 AM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 24489 ms
    DispatcherServlet with name ‘petclinic’ determining Last-Modified value for [/petclinic/pettype]
    Mapping [/pettype] to handler ‘com.springsource.petclinic.web.PetTypeController@68f507d2′
    Last-Modified value for [/petclinic/pettype] is: -1
    DispatcherServlet with name ‘petclinic’ processing GET request for [/petclinic/pettype]
    Invoking request handler method: public java.lang.String com.springsource.petclinic.web.PetTypeController.list(org.springframework.ui.ModelMap)
    Resolving exception from handler [com.springsource.petclinic.web.PetTypeController@68f507d2]: java.lang.NullPointerException
    Resolving to view ‘uncaughtException’ for exception of type [/java], based on exception mapping [.lang.Exception]
    Exposing Exception as model attribute ‘exception’
    Handler execution resulted in exception – forwarding to resolved error view: ModelAndView: reference to view with name ‘uncaughtException’; model is {exception=java.lang.NullPointerException}
    java.lang.NullPointerException
    at com.springsource.petclinic.reference.PetType_Roo_Entity.ajc$interMethod$com_springsource_petclinic_reference_PetType_Roo_Entity$com_springsource_petclinic_reference_PetType$findAllPetTypes(PetType_Roo_Entity.aj:64)

    [Edit: cutting off the stack trace slightly to make comments more readable]

    thanks, hope the back feels better!

    May 02, 2009 @ 04:58


  18. sschmidt

    @rhart & @Jules,

    The problems you are seeing are probably due to the fact that you are deploying the application without AspectJ weaving enabled. The compile-time weaving takes place when you generate the application with mvn install from command line (thanks to the eclipse AspectJ plugin), or, when deploying from Eclipse you need to install either the ROO eclipse plugin (see http://www.springsource.org/roo) or the AJDT (latest dev build). Essentially you need to make sure that the spring-aspects.jar archive is on your classpath to take care of the aspect weaving.

    -Stefan

    May 03, 2009 @ 13:14


  19. rhart

    YEY all sorted, thanks! Now the fun can being :-)

    May 04, 2009 @ 23:20


  20. Laurent

    new persistent class jpa -name ~.domain.Item Fails (Mac OS X + Java 5 / 32bits)

    Exception in thread “main” java.lang.UnsupportedClassVersionError: Bad version number in .class file

    [Edit: cutting off the stack trace slightly to make comments more readable]

    May 05, 2009 @ 08:10


  21. Niel Eyde

    If you’re interested in understanding the code generation options that are available for Spring, you should check out the following blog post “Spring Roo, Skyway Builder and code generation”.

    http://www.skywayperspectives.org/blog/?p=647

    [Note from Ben Alex: I have responded to the specifics raised in Skyway's blog in the response section of their entry; a permanent archive of the response is also available here]

    May 06, 2009 @ 00:45


  22. jpolo

    Keith,
    Your snide remarks not withstanding, Java devs wishing to not jump on every trend are not akin to Cobol developers.

    For one, grails does not even play well with standard Maven conventions and allow for integration with other standard java code libraries as part of an overall build. And the “we are not going to adopt maven” stand of the grails guys is juvenile at best.

    May 07, 2009 @ 05:43


  23. depy

    Hi!

    Seems like a tool that I wanted. :)

    But the question is (I not that much informed with appfuse and similar projects): can you customize the GUI, or make your own theme? Or how does it works?

    Cheers!

    May 07, 2009 @ 18:55


  24. chris

    Is it possible to run the war inside jetty? The problem is that mvn jetty:run re-assembles the war without the AspectJ weaving.

    May 08, 2009 @ 04:31


  25. sschmidt

    @depy

    We are looking into this and should have something more flexible available soon.

    Stefan

    May 08, 2009 @ 14:17


  26. sschmidt

    @chris

    I have not tried this yet. This would be something that needs to be lodged in a public Jira which we are planning to make available very soon.

    Stefan

    May 08, 2009 @ 14:18


  27. Porter

    Is there any _easy_ way to use enumerated elements with Roo? I just figured I’d try out a little experiment after getting the pet clinic sample up and running…

    On the AbstractPerson class:

    @Enumerated(EnumType.ORDINAL)
    private Gender gender;

    And then, in the domain package:

    public enum Gender {
    FEMALE, MALE;
    }

    I believe I let Roo manage the files – and saw a few messages indicating it had updated some of the resources.

    Unfortunately, I only see error messages when I attempt to Create New Owner. I’m just guessing, but it seems the code generation has no easy way to know what sort of widget to use on the generated web page for object attributes which are enumerated.

    May 13, 2009 @ 05:57


  28. sschmidt

    @Porter,

    Yes this is something we have not looked at yet, but it should not be hard to deal with it in a future version.

    Thanks for making us aware of this.

    Btw. there is now also a forum where we do answer such questions / feature requests: http://forum.springsource.org/forumdisplay.php?f=67

    -Stefan

    May 13, 2009 @ 12:24


  29. sschmidt

    @Porter

    Since we now also have a Jira for Roo, I have taken the liberty to lodge a ticket for this bug.

    http://jira.springframework.org/browse/ROO-7

    You can watch the progress on this issue if you wish.

    Best,
    Stefan

    May 14, 2009 @ 17:18


  30. Kevin

    Hello, Stefan.

    It’s Kevin.

    When I got the release news of ROO, it reminded me that not too long ago, you casually mentioned something new which you were involved in its development was coming up from your company soon. I simply guessed ROO must be the one as it seems to be really nice and I don’t think you could be bothered to mention it if it weren’t that cool. :D And besides, ‘ROO’ does sound Australian although I heard that ROO stands for ‘Real Object-Oriented’. :)

    Anyway, mixin using inter-type declarations of AspectJ in Spring ROO is great! It is really good Separation of Concerns (SoC) I think.

    I wrote about Spring ROO on my blog.
    http://blog.lckymn.com/2009/05/17/roo-so-cool-01/

    There are 4 posts + 1 extra post yet if I put all the URLs, your blog complains my comment seems spammy. :)

    These include feedback about ROO as well. I actually tried ROO about 2 weeks ago yet didn’t have time to write about it.

    Again, ROO is really nice! Awesome!
    Thanks Stefan and SpringSource for such a nice technology. :)

    Regards,
    Kevin

    May 18, 2009 @ 08:44


  31. depy

    I actually tried it and I really like, but I have another question.

    Will there be any way to turn off the stuff you don’t want to use. For example if I dont want those JS effects, could I turn this off somehow?

    Best regards,

    Matjaz

    May 22, 2009 @ 18:12


  32. sschmidt

    @depy,

    Removal of view artifacts is currently not supported. However since the controllers are exposing all resources via REST you can replace the view technology to your liking. Also, you can remove the JS artifacts manually and switch of auto-generation of view artifacts in the controller annotation (automaticallyMaintainView=false).

    We have also separated the JSP (and Dojo) code generating add-on so that there can be easily alternative solutions provided in the future.

    You are invited to lodge a improvement request against the Roo Web component in the Roo JIRA: http://jira.springframework.org/browse/ROO and assign the ticket to me (sschmidt).

    Thanks,
    Stefan

    May 22, 2009 @ 18:28


  33. depy

    Sounds like it will be very flexible. I like it. :)

    If I remember something I’ll use the jira.

    Wish you good luck with Roo and can’t wait for more good news.

    Regards,

    Matjaz

    May 22, 2009 @ 19:42


  34. Haikal

    New mvn install command should be:

    mvn install:install-file -DgroupId=org.springframework.roo -DartifactId=roo-annotations -Dversion=1.0.0.M2 -Dpackaging=jar -Dfile=$ROO_HOME/dist/org.springframework.roo.annotations-1.0.0.M2.jar

    Jun 24, 2009 @ 21:03


  35. Stefan Schmidt

    Haikal,

    Thanks for updating this :) .

    -Stefan

    Jun 24, 2009 @ 21:26


  36. Rega

    Hi,

    I tried running the ‘shoppinglist’ sample application. I followed the steps (in development mode) that I show you here,

    windows XP
    java version “1.6.0_07″
    apache-maven-2.1.0

    create project -topLevelPackage net.stsmedia.roo.shoppinglist
    install jpa -provider HIBERNATE -database MYSQL
    new persistent class jpa -name ~.domain.Item
    add field string -fieldName name -notNull
    add field string comments -sizeMax 150
    add field number -fieldName price -type java.lang.Float
    new persistent class jpa -name ~.domain.ShoppingList
    add field string -fieldName title -notNull
    add field date jpa -fieldName shoppingDate -type java.util.Date
    add field set jpa -element ~.domain.Item -fieldName items
    new controller automatic -name ~.web.ShoppingListController -formBackingObject ~.domain.ShoppingList
    new controller automatic -name ~.web.ItemController -formBackingObject ~.domain.Item

    but when I try to executed the ‘new controller …’ step I got this error: [...]

    I’ve tried another example, like Ben’s ‘wedding’ and everything was ok. Please If someone could help me with this error I’d appreciate it a lot.

    Cheers!

    Jun 26, 2009 @ 22:29


  37. Stefan Schmidt

    Rega,

    I have just tried to replicate this but could not. Can you please let me know which Roo version you are using?

    -Stefan

    Jun 27, 2009 @ 10:50


  38. Stephen

    @Keith

    Hi Keith,
    Not all Java developers spend all day developing CRUD applications.
    All tools have their own merits and are usually developed when someone sees a need for them.

    Stephen

    Aug 11, 2009 @ 16:57


  39. Frankie Huang

    When the ROO’s documentaion will well-prepared?

    Dec 26, 2009 @ 14:26


  40. Rafael

    Hi,

    another Spring ROO Article you can find here.

    http://www.developers-blog.org/blog/default/2010/02/16/Spring-Roo

    Rafael

    Feb 19, 2010 @ 05:36

Reply