rails

Grails - The Good, The Ugly and The Bad

Grails is a great framework, clean and powerful.

It was inspired by Rails. Rails is a good framework that proved the web development can be a lot easier. The drawback of rails is ActiveRecord, the database layer framework. ActiveRecord is a elegant solution for simple databases. The drawback is the last sentence is the "simple databases". It demands that the database was created with specific characteristics what make useless when you need to interface with a already defined database. If you cant change the database scheme to fit his limitations you have to drop rails from your project. It is not a bug, rails was designed that way, it was a conscientious choice between simplicity and functionality. But IMHO they oversimplified, but it works really well if you can design (or redesign) your database from scratch. In some environments this can be acceptable, in others don't.

Grails keeps the dynamic functionality of Rails, it uses all dynamic functionality of groovy but, instead of using a implementation of ActiveRecord, it uses a dynamic layer (GORM) on top of Hibernate. Hibernate it's one of the bests ORM frameworks. It is simple, flexible and powerful. The hibernate design is modular you can plugin a lot of different strategies to get the connection, different implementations of connection pool, cache manager. So using Hibernate was a really good option. Grails got the dynamism of Rails without its limitations. They made a really good job in this point. Another strong point is the template system, sitemesh is a powerful template system designed specific to use in web applications (they prefer to describe it as a "web-page layout and decoration framework", but for me still been a template system). I never used sitemesh before and I really enjoyed the experience it is a really clean approach to create the layout.

In Rails they have commands to generate code. In Grails they create the same. This make sense because there they don't have a tool do make the bootstrap of the application in the ruby environment, so they created this command on top of Rake (build system in ruby).

What they don't realized in grails project is that in java we have this tool! We have Maven.

Maven is a fantastic tool, the type of tool that we wish to exist in every language. It's a modular project build tool. It is able to manage dependencies, build cycle, testing, packaging and publishing your artifact in the repository. It's a project build tool, a step ahead of the normal build tools (actually the first version was a layer on top of Ant). It provides a default directory layout for your project and really nice defaults, all you need to start is choose a name for your project and the default package to create. Everything else works out-of-the-box and if you need anything different you can provide configuration in the last case you can provide a new plugin that will be managed by maven repository (the plugin is just another type of dependency and it will be download automatically after you configure in your pom). It uses convention over configuration much before rails community coined the term.

So, instead of making a download and installing a grails environment if it was using maven all we need is to download a archetype with all dependencies configured.

Instead of

grails create-app name

could be just

mvn archetype:create -U \
-DarchetypeGroupId=net.liftweb \
-DarchetypeArtifactId=lift-archetype-blank \
-DarchetypeVersion=0.4 \
-DremoteRepositories=http://scala-tools.org/repo-releases \
-DgroupId=your.proj.gid -DartifactId=your-proj-id

Observe that is not necessary to install anything, it just a matter of running one command. This example I took from liftweb. Liftweb is an interesting framework, it's another clone of rails but in scala. Scala is a really nice functional language on top of jvm, but liftweb have the same problems of Rails, they use a re-implementation of ActiveRecord instead of reusing hibernate as its ORM layer. But they made a nice work using maven instead re-inventing the wheel (so they reinvent just one square wheel). In grails they made the opposite, excellent database layer but reinvent the square wheel instead using maven. The liftweb project is in the beginning if they change the database for something like GORM (a dynamic implementation on top of hibernate), this is a serious candidate for a killer-app and help to spread scala (interesting, like rails spread ruby and grails is spreading groovy right now).

Instead of

grails create-controller name

nothing!!

A controller in grails is really light, the command above just create a empty class in the proper directory with that name and the respective empty test in another directory. Both are just stubs created with the right name. They can be easily write by hand, anyway we need to go to then to put functionality and test, avoiding needing an extra command to handle that. If this to line stub is a big deal for anyone it's easy to create a template of a groovy class, there is nothing special in a controller besides it's name, it's just a POGO (Plain Old Groovy Object, ok, I made-up this name). This simplicity shows how great grails is, but put a command to do this simple task create a unnecessary extra step.

Instead of

grails run-app

could be just

mvn jetty:run

This command start jetty configured to reload the files from the the source directories (the standard directory in the maven default project layout, you can change if you have specific needs, if you don't it works out-of-the-box) This works even to test jsp's on-the-fly. So why reinvent the wheel?

My point is why not try avoid the grails command in favor to use a plugin for maven? This will make a lot of things works out-of-the-box to grails with no extra efforts. Put this things out of the way for the grails developers (the developers that created and maintain grails, not the developers that just use it).

Just as an example, try to imagine how to reimplement this using the grails command. When we ask maven to create a package (mvn package) it automatically run the tests. It will automatically run the tests (junit or testng, you can choose) in src/test/java (the groovy plugin configures test plugin to search for tests in src/test/groovy). If you want a different location you can provide one variable in your pom file to say where to look (one or more directories). If you need you can provide a list of test cases to include (default: **/Test*, **/*Test.java and **/*TestCase.java) and/or a list of test cases to exclude. If you need to run just one test case you can provide another variable that will override the include/exclusion list (test=YourTestClass). If you want to skip all test cases you can just provide another variable (maven.test.skip=true). And all this variables can be provided in the configuration file (default behavior of your project) or in command line (which make more sense for commands run just for temporary needs like run a single test or escaping all test case).

Now how much effort is needed to put all this functionality and fall backs in the grails commands? And that is just one maven plugin! There are a lot more! I didn't talked yet about a lifecycle management of maven or even dependencies management (maven's dependency system has transitive dependencies and scopes of dependencies, I will not explain this points now but if I decided to remove all groovy libraries from my war all I have to do is just change the scope of the dependency).

Anyone want to try re-implement all this functionality on top of grails? or keep maintaining a half implemented build system?
So why not gain all this for free? Throw away the grails command. Keep what is great in grails. Use what is great in maven.

2008-01-31 Update: The discussion follows in http://graemerocher.blogspot.com/2008/01/why-grails-doesnt-use-maven.html and http://jonasfagundes.com/blog/2008/01/the-misunderstood-maven.

Syndicate content