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.

Comments

Maven Tools for Grails

Graeme Rocher responded to your post by detailing some of the reasons why the Grails team didn't use Maven:
http://graemerocher.blogspot.com/2008/01/why-grails-doesnt-use-maven.html

And regarding your last question, there's already a Maven plugin that sits on top of Grails that you can use:
http://forge.octo.com/maven/sites/mtg/

Most of the Grails commands are replicated through Maven dedicated goals.
I've used this plugin myself to easily integrate a Grails app in my continuous integration server of choice, and to be able to depend upon existing in-house libraries stored in an Enterprise Maven repository.

Maven Tools for Grails

Guillaume,

"Most of the Grails commands are replicated through Maven dedicated goals."

You got my main point. They are replicated. I think this redundancy should be avoided, use the tool instead of writing a half-reimplementation.

I'm writing another article about the Graeme's article. I just need some time to finish.

Thanks for your comment,
Jonas Fagundes

waiting

I will be waiting for your Graeme's article.

Regards
David (Custom Term Paper)

You predicted the future in this post

Your post is almost the predict my future story about Maven :)

lift works just fine with Hibernate

Jonas,

A couple of things about lift:
- It works just fine with Hibernate. lift's built-in OR mapper is a very simple and oriented toward getting simple projects up and running quickly.
- lift is not a Rails clone. lift uses a "view first" rendering strategy, is component oriented, stateful, and has seamless server push.

Thanks,

David

Liftweb with Hibernate

David,

I'm glad to know that liftweb works with hibernate.

In hibernate to map a class all that is necessary is to write one xml (or put annotations in the class).

In GORM they improved because they use defaults for the mappings:

class DomainClass {
  int someIntProperty
  boolean someBooleanProperty
}

but if you need to change any of the default behavior all you need is to provide it. Suppose I need to change something (for example the table name), all I need to do is

class DomainClass {
  int someIntProperty
  boolean someBooleanProperty
  static mapping = {
    table 'table_name'
  }
}

In GORM make it even more simpler because they add to domain class some handy methods to interface with hibernate , it's not necessary to use any Session/EntityManager (thanks to the dynamic features in groovy).
This simplicity doesn't add any restrictions to what I can do. This is what I like in hibernate. This is what I like in GORM.

This could be a good solution for simple projects but difference of simplicity betwen using hibernate and an ad hoc implementation of an object-relational mapping framework is not worthy in my projects to make me accept the lack of flexibility in the more complex situations.
This is not a issue of the implementations, but a design choice between Active Record (more simple and less flexible) and Data Mapper (can be more complex but it is more flexible).

IMHO hibernate is powerful and simple enough, but if anything better than hibernate appears in the horizon, it will be really interesting to see. (In 2004, I tested use prevalence of objects for simple projects instead using relational database, but I realized that was much simpler use hibernate with hsqldb than using prevayler with jxpath (instead sql) to make the queries.)

Could you provide links to the documentation/examples of liftweb using hibernate, please?
It will be really nice to test liftweb with hibernate.

Thanks for your work in liftweb,
Jonas Fagundes

maven ???

i am new in java and i am glad to see that Grails was exist in java world. I was longging to learn about the hibernate and so on and wish to learn more about java. but the pure java frameworks were not easy to learn. it takes times.

i see grails as a breakthrough (and groovy as well ... cheers ! ).
when I read about your article and you complaining why grails not using Maven ... I think maven was so complex.

like you said above
this command grails create-app name

is same if written in maven :
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

do you know, for the beginner (like me) ... those 7 lines of code will scary them away from learning grails. I love the way grails ... it is so simple .. it looks like rails one. and it is the best thing i found in grails. :)

Maven Fears

Hi,

You don't need to be scared. Everything should measured in terms of the benefits and the complexity it aggregates to your project.

That command line (it is not code) is executed just once, just to create the project and it works out-of-the-box.

After the project is generated all you need to execute is

$ mvn package

to
- verify all dependencies of your project;
- download the ones you don't have locally;
- put them in the classpath of your project;
- compile your project;
- compile your test cases;
- run your test cases;
- verify if your test cases finish with success and
- package your project.

Now you can evaluate better the benefits of using maven against the complexity it adds.

You don't need to be scared. Knowledge can be scary sometimes but ignorance always is.
Don't make decisions on appearances. Learn if the technology help you to reach the goals of your project.

Cheers,

What would you propose then.

What would you propose then.

You need to write books ;-)

You need to write books ;-)

nice

nice post and blog. Thanks for sharing

It is written dryishly, but

It is written dryishly, but it is all the same entertaining.

Meta Expires

very intresting blog with such an intresting & nice article.Thanks for sharing it.keepup the great work...

The post is great, keep on

The post is great, keep on sharing

I have tried to read what is comment in chines but failed. This post should also include some translator... (Just Kidding)

Thank You

Thank you for your great article.

Thanks...lot's of great

Thanks...lot's of great information between the two. Looking for ward to more information on Graeme.
Sharon

Hardware

"Thanks for provide me this informative info. Great! I am really waiting for your next post.

Thanks for sharing!"

Thanks..

I have been working on finding advantages and disadvantages of these new technologies for my organization ... We are thinking to shift to one of the new technologies that could be really beneficial... I am personally working on Java technologies... And this article has helped me a lot giving final touch to my presentation this weekend... Thanks a lot... Great help.. Any more suggestions if you can give me I will be happy to read them...
Thanks again..

Comment

Thanks for provide me this informative info. Great! I am really waiting for your next post.

Awesome information

Awesome information you have here. Just wanted to say that I appreciate it.