Groovy and Grails
Grails is an amazing Web application framework. It's great to see a dynamic language like Groovy executing in the JVM, leveraging APIs written in Java together with really exceptionally support for collections, due in part to Groovy's use of closures. In addition, Groovy is a language that seduces you to use Test Driven Design (TDD) - you just can't help yourself because it comes with support for unit testing and mock objects.
Grails carries over Groovy's advantages and uses the Rails paradigm of convention over configuration. Grails implementation also uses flexible, but solid, APIs for the implementation - Spring and Hibernate.
I just wrapped up an interesting project implemented in Grails. (Here comes the shameless plug - "as most projects are at The Code Works".) Now I have to say - I love using Grails. Development speed was really fast compared to a traditional JEE application. I could try out a prototype implementation of a piece of the application architecture without investing too much time - I really could develop using "throw away" code. Changes to any layer - view, controller, or domain classes were automatically compiled and deployed to the running server. I could see the effects of my changes immediately. It really was amazing to see how fast one could have a working version up and running in such a short period of time.
The Gotchas
I think Grails has a great future and while the present 1.0.1 version is good, I have found some "gotchas" that developers should be aware of until later versions of Grails resolve them.
Testing
The most disappointing gotcha is the current level of support for testing. Grails has three levels of testing - Unit, Integration, and Functional. Unit and integration testing come out of the box with Grails, while functional testing support can be added through the WebTest plug-in.
The unit testing implementation doesn't provide the "convention" part of the runtime environment. It doesn't know for example that a class named with the "*Controller" convention should have methods and properties provided in the Grails runtime environment such as params, render, session, request, and response. The developer needs to provide a mock implementation of those runtime Controller methods.
One could be tempted to give up on unit testing and just use Grails integration testing support because the Grails development environment is so fast. Unfortunately, the start-up time for the Grails development environment is not that fast. If one were to execute a simple, single integration test, the development speed would be severely degraded. On my development machine, just the start-up of the Grails development environment took 15 seconds.
In addition, the integration test runtime does not handle for the AOP methods called before and after a Controller action is called - beforeInterceptor and afterInterceptor. (In the project I just completed I used the Aspect methods to implement client state management because the built-in state management API using WebFlows, is incomplete in the Grails 1.x version.)
Finally, the functional testing support provided by the Canoo WebTest plug-in was disappointing. The plug-in provided a 0.x version of WebTest that was too buggy to really use. In the end I used the 2.5.4 version of WebTest. I put the WebTest library in the Grails project, provided minimal integration by modifying the Grails project build.xml and used the standard XML interface to call the API, instead of the Groovy interface.
Again, we're talking about a 1.x version of the Grails API. I feel certain that later versions will provide much better support for testing so that TDD will filter from Groovy through to Grails.
Prototype API
I was really eager to use the Prototype API for coding Javascript. It really is a great improvement over having to implement code to handle the vagaries of different browser implementations. The only gotcha here is that the integration into Grails is still a little shaky - there are some bugs in the code generated by the Grails tags for the Ajax remote calls. In This is also the place to note that Grails 1.0.1 documentation is also incomplete or just plain wrong. I think it's time for an overhaul in the documentation.
Automatic compilation
The feature to auto-compile and deploy to a running server is great, but there are two items to be aware of. The first is that if you made a change and you don't notice any difference in the functionality of the application, it could be because the compilation failed, no change was made to the deployed application, but no notice will given, unless you set log4j debugging correctly. However, you WILL notice it the next time you try to run the application because you will get a compile error message and the server will not start-up. (At least you don't have to set the logging and then run the application to see the error!)
The second item is that auto-compile of domain classes will cause the Web application to restart, so if you have an application that utilizes the HttpSession (is there one nowadays that doesn't?), any current sessions will be lost.
Data-binding and Validation
This is truly a great feature of Grails. It is just so, so easy to bind the HttpRequest parameters to the domain classes in the controller that you'll have tears come to your eyes the first time you use it. Have a box of tissues next to you if you've been doing Web application development for a few years, you're gonna need 'em. The Grails tags to handle error presentation using the message.properties resources with easy to use i18n support are a joy too.
Here another helpful point - both data-binding and validation generate error messages that can be retrieved from the domain class, but not together! If you call for validation on a domain class that had data-binding errors, you'll lose the data-binding error messages. In my recent application, I had the controller return any data-binding error messages to the client for correction. Only after the client presented a request without data-binding errors did the controller proceed to validate the domain class according to the constraints.
Dynamic vs. static typing
Dynamic typing is bedrock of Groovy, without it, it's pretty limp. But this is definitely something that will bit you time and again in your development - believe me, I still have the bite marks from this last project to prove it! When you see a def statement in your code, make a test for it right away if you didn't have one already. Better yet, ask yourself why you have a def at all. If you don't need it, drop it.
Domain class hierarchy
Grails gives you GORM, Grails Object Relational Mapping using the Hibernate API as its base. It really cool because it's even easier to use than Hibernate's XML mapping. But here's something from my experience: GORM by default uses a Set in runtime for the hasMany relationship definition. I strongly recommend keeping in mind the possibility of explicitly using a List implementation. I came upon a problem when adding multiple new records to the "many" side of the domain relationship. My application had to allow the addition of multiple new records along with already existing records in the same view. A new record would have no unique id yet and if there were some data-binding or validation error in the new record fields, the error messages be difficult to relate to fields in the view. I solved it by explicitly using a List instead of the default Set. Now all records, new or existing, would have common unique id through the index in the list. I appended the list index onto the appropriate field names in the view and thereby related the view fields with the fields in the "many" domain classes.
Summary
I think Grails is a truly great Web development framework, despite its current version 1.0 issues. It's hard not to fall in love with it. I hope my experience described above will help others while they're having fun with Grails. I know I'll probably be saying in my next straight JEE Web application: "in Grails this came out of box".
References