Grails thoughts

Grails command-line utility is based on Ant. This seems really cumbersome to me since Ant is the complete opposite from a CLI framework. Some of the more annoying things are the lack of CLI switches and lack of the ability to pass parameters. Instead it reads from stdin when doing pretty much anything. Like this:

brian@brian-desktop:~/dev/java/grails-tests$ grails create-app foo
Buildfile: /home/brian/dev/java/grails/src/grails/build.xml

init-props:

create-app:
    [input] Enter application name:

Pretty annoying.

Second of all, the code generation uses tabs. This is just a preference thing but really they should go ahead and stick to the Java coding standards to get the best coverage.

Okay, been trying to get a simple app up and running and thus far I’ve had a considerable amount of headache with the generator system. If you add new field values in a model you need to delete and re-generate the entire controller/view layer in order for them to show up. This is really cumbersome. They really should scaffold out the view just like Rails does so that adding new fields is straight forward for a scaffolded app. I think this is just because of the generation. I’m going to try scaffolding next… Here goes.

Okay, so scaffolding like this works:

class FooController {
  def scaffolding = true
}

I wonder if they let you selectively override certain methods like Rails does… Let’s find out. Yep, selective overrides seem to work fine.

Okay, next annoyance… In Rails you can add new controllers and domains as you go. In Grails you can’t add new controllers or domains. Well, I’m not positive on the domain front, but it seems that way since if you can’t add controllers you might be able to add a domain, but probably won’t be able to do anything with it. This really slows development time down compared to Rails. This means a server restart each time you add something new.

Next, I never harp on naming except right now. This is something they have to change for everyone who uses Linux, a shell and the tab key (or if you use XP and cygwin). There are two directories in the root of the project that have the same prefix:

brian@brian-desktop:~/dev/java/grails-tests/grails-hibernate-test$ ll
total 36
drwxr-xr-x 9 brian brian 4096 2006-09-25 14:03 grails-app
drwxr-xr-x 2 brian brian 4096 2006-09-25 20:55 grails-tests
...

This must change and really there is absolutely no reason these should not be named app and test. The fact that I can’t type in one or two characters and then hit tab is REALLY annoying and very slow. Another naming annoyance is in the grails-app directory:

brian@brian-desktop:~/dev/java/grails-tests/grails-hibernate-test$ ll grails-app
total 28
drwxr-xr-x 2 brian brian 4096 2006-09-25 21:10 conf
drwxr-xr-x 2 brian brian 4096 2006-09-25 21:01 controllers

Typing in con is not enough to resolve the directory name. In fact I should only have to type in 1-2 characters. Anyways, just a simple annoyance. They could move conf or call it something different and save a lot of folks some serious headache.

Oh the evil copy issue! It bites everyone at some point and it seems that Grails decided to use this as there preferred mechanism. They apparently make a copy of the web app to a dir called tmp and run it from there. I guess they must run some type of checker that looks for file changes and then copies files over or something because Windows without junctions doesn’t have symlinks and there aren’t any symlinks in there. Anyways, if you create a domain and then later delete it you must delete your tmp directory! Even if you stop and restart the container this tmp directory never gets cleared. This is a bummer. They really should find a more elegant way to handle things. At least you can count on Rails never using a copy of any Ruby class, even the rhtml files that are interpreted by the ERB (if I recall).

The sum up, the reason I did this little exercise is that I wanted to test out whether or not Hibernate would work as the ORM layer. I’ve had a lot of issues with Hibernate including collections, sessions/transactions and of course the nasty session corruption issue that I haven’t written about yet, but a lot of folks have issues with where things like a unique key violation will completely kill the session making the use of open session in view filter very difficult. So, I wanted to test mostly the use of collections and the session/transactions issues. Here is everything I’ve found

  • Grails scaffolding blows up when there are any database errors (unique key, whatever). This causes a stack trace and the error page
  • Grails, like every other Hibernate application still has problems with the sessions and immediate updates. I setup a simple test that would update a row with a unique key violation. According to GORM, the update was successful (i.e. user.save() == true). This is because Hibernate said it was successful. Hibernate is really dangerous in this respect because it doesn’t do the update immediately and instead caches it for later. This is large and nasty and I’ll write about it later.
  • Grails still suffers from the open session in view syndrom. They might not actually be opening the session in the view to support lazy loading (I couldn’t determine this without looking at the code), but they have the same issue. If I update the entry and cause a unique key violation and do a redirect, well everything is okay, because it is a new session. However, if I use a forward, then it stack traces and I get the error page. This is because the session is totally jacked the second a database exception is hit. Again, large and nasty and I’ll write about this later.

So, my suggestion to the Grails folks is bail on Hibernate and either use something better like iBatis that can handle unique violations and doesn’t cache updates and all that crap that Hibernate does or write your own. You’ll end up pissing off so many Rails people looking to come back to Java that you’ll end up losing them forever. Not to mention battling with Hibernate forever since Gavin seems blind to the fact that the session was a really bad idea.

More later as I keep working with Grails.