Jens Krämer

How I learned to stop worrying and love JRuby on Rails

 |  hibernate, jruby, grails, j2ee, webit, rails

As I wrote earlier, I got pretty excited about JRuby and especially about the idea of running Rails on top of it at RailsConf Europe. By pure coincidence we had just had started a project at webit! at this time which had to be deployed to the customer’s J2EE infrastructure. I didn’t really follow the JRuby development before, and therefore greatly underestimated its level of maturity. So, looking for a Rails-like way to build this application, I decided to go with the Groovy-based Grails framework.

At first Grails looks and feels much like Rails, however if you look closer and actually try to build a real application with it, the differences start showing up. Don’t get me wrong, when compared to the more traditional J2EE ways to build web applications (my experiences in this field range from plain Servlets to Struts and Spring), Grails is a huge step into into the right direction. Unfortunately for me, coming from Rails, it just didn’t feel right or complete in many places. Partly this is for sure because Grails, despite its name, is not just a Rails clone, but does things in its own way in many places. Without going into much more detail here, things often weren’t working the way I expected, and documentation was often outdated or missing.

Another issue with Grails for me was Hibernate, its persistence layer of choice. I simply can’t get used to the way Hibernate works. In my opinion it abstracts way too much from the database with its own query language and all its object oriented query building glory. Also it seemed to queue up sql statements and execute them at will at some later time, which I found irritating to say the least. I really don’t understand why Hibernate is the persistence framework of choice in so many J2EE projects. On the other hand it fits the ugly picture of the bloated J2EE web application quite well ;-)

To summarize this rant, don’t underestimate the learning curve of Grails, which will be even steeper when you aren’t already used to Hibernate. I think Rails people having to do J2EE development are just not the target audience of Grails. But it might be a good fit for J2EE developers who either already have their Hibernate models in place or at least have the will to invest some serious time in learning Hibernate.

After all, as you might already have guessed, I decided to start from scratch with JRuby and Rails after RailsConf Europe. And it really felt like coming home from a long and exhausting trip. Despite the lost time in the beginning we met our deadline and had a really great time solving problems the Rails way and deploying to JBoss every now and then. Right now I’m in the middle of my second JRuby on Rails project, same customer, same target platform. I plan to write some more articles about our experiences with JRuby, so stay tuned.



"Without going into much more detail here, things often weren’t working the way I expected" - that is not a particularly useful or thought-provoking statement !

As for hibernate and layers of abstraction...Grails goes one or several layers of abstraction even further - all for the good. Have you even tried the Grails ORM properly ? Maybe we should all start writing in assembler again ?


Joe, thanks for your comment.

First of all, we had to deal with a legacy db schema which forced us to use hand crafted hibernate mappings since Grails ORM didn't support several of the constructs we had to use there in its DSL. The other problem was that said legacy db schema also had a lot of views and stored procedures we had to use, leading to a difficult situation for any OR mapper.

I found it far easier to use ActiveRecord with this kind of database because it is much easier to build hand crafted sql queries with it.

For the things that weren't working the way I expected - I didn't go into more detail because it wasn't my intention to do a comparison of Grails and Rails in terms of features or usability or whatever. I simply haven't used Grails long enough to do a fair comparison, and I think Grails is still a fast moving target so many of my points are probably no issues any more.

Anyway, here are some examples: Back then you couldn't have multiple filters around your controller actions. If you e.g. defined one global before filter for checking authentication, and then another one inside a specific controller, the latter replaced the global filter instead of being executed in addition to it. Not very useful for me as I can't imagine coding an application in a DRY way without applying multiple filters both application-wide and per controller. Of course it's not hard to build this feature yourself, but I think this is a core feature which just should be correctly implemented by the framework. I just checked and it seems this issue has been fixed in 1.0 with a more generalized Filter approach. Don't know if they also fixed the problem that filters couldn't load records in a way they could be accessed in the view without the need to place them in the session.

One other thing that really disturbed me was how testing works in Grails - basically you don't have any part of your application set up for you in unit tests (especially no database connection), and nearly nothing in functional tests, especially no services had been injected in controllers. That of course might be a matter of taste, but I much prefer the kind of full stack testing Rails allows me to do, including loading of fixtures into the test db.

Now add the fact that logging configuration sucked to the point I simply couldn't get it configured the way I liked, and Groovy stack traces which were at least a mile long doing a great job hiding the root of any problem, and you can get frustrated really fast.

And no, I won't do assembler again - however SQL was invented to query data stored in relational databases, and I don't see any use in a persistence layer that invents it's own SQL look-alike query language for this purpose. Grails ORM looks nice from the examples, but it's nothing a Rails user hasn't seen already long ago.