I've spent the past couple of weeks reading up on Grails, a web application framework inspired by Ruby on Rails. It takes advantage of Groovy, a dynamic programming language that runs on the JVM and is best described as a cross between Java and Ruby. Groovy has support for most existing Java syntax, but also a lot of Ruby-style syntax and dynamic features. To be honest I find that the Java aspects of Groovy (and Grails) drag the whole experience down a bit compared to writing Ruby, but it should be significantly nicer to work with than pure Java.
The big selling point of Groovy and Grails over Ruby on Rails comes from the compatibility with the whole Java ecosystem. You can have your clever dynamic language without giving up the Java libraries and deployment environments that your projects and customers may demand. This is clearly quite a compelling idea if like me you've got a long history of doing big Java web apps but have recently been converted to the dynamic cause.
One thing that is very important to realise is that Grails is not a port of Rails. It is in fact built on top of the Spring stack, including Spring MVC, REST support, dependency injection, transactionality and Hibernate amongst others. If you're already familiar with Spring this is probably a good thing, though I do worry that the framework on top of framework approach could lead to having more to learn (and mess up) overall.
My initial experiments showed an interesting result that rather worried me. I set up a domain class and a controller with def scaffold = true to provide built-in CRUD for my domain class. However the CRUD pages this presented were noticeably sluggish in the browser and benchmarking confirmed it could only manage about 2 requests per second. This is lamentably poor and even now I can't figure out how it's managing to spend so much time achieving not very much.
After a bit of experimentation I determined that if I use grails generate-all to put the scaffolding code in place in my classes (rather than using the dynamic scaffolding) then things speed up enormously. In fact I can now get about 200 requests per second. It's hard to see how there can be such a massive performance gulf between the two scenarios as I would have thought that the only extra overhead for dynamic scaffolding is the initial dynamic intercept of the missing action method and calling into the scaffolding code. Hopefully a Grails expert can explain this, or I will eventually figure it out myself. At least now I have determined that for real-world scenarios there isn't going to be a performance issue, though I am surprised that the Grails docs don't have a massive "Warning - dynamic scaffolding is really slow" box.
For now I haven't done much but read the docs and try a few things. I hope to get deeper into it soon.