Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreGrails seems to be going from strength to strength, and it looks like it definitely "has legs", as they say. I am quite interested in stretching those legs a little outside the web application arena. If you are aware of my work on Spring Batch, you will probably be able to guess where that might take me. But for this article I wanted to just share some experiences I've had with the basic, low-level deployment and build of a Grails application.
I have a love/hate relationship with Maven 2, and I am learning to love Grails, but sadly the two do not play particularly well together. It would be really nice to see tighter integration. Maven is not always everything we want it to be, but there are some things that really make it worthwhile. It is a standard of sorts (love it or hate it) so when I download a project from somewhere I already know how to build it, what its dependencies are and where the documentation is. Grails has some of the same features, and in fact includes its own quite sophisticated build tool based on Groovy scripting of Ant. Maybe there is a middle way, where we can have the best of both worlds?
I am also aware of some other activities in this area, and I hope we can coalesce around something (maybe driven from the discussion in this forum and in the Grails JIRA). For instance see Frederick Verbist's blog and Arnaud Heritier's maven integration project (only barely underway at this point). The Grails team is traditionally unimpressed with Maven (e.g. see here), but I had a chat with Graeme Rocher, and he is open to suggestion, so I hope we can make some progress here.
In the spirit of taking some simple steps towards maven integration, I have attached a set of poms that describe (roughly) the dependency structure of Grails as I am aware of it in Grails 0.5.6. Ignore or change the Spring version number if you have issues with it - Grails 0.5.6 uses Spring 2.0, but I needed 2.1 for a project I am working on. Graham says Grails might not work properly with later versions of Spring so your mileage may vary. That's the beauty of Maven right? You can see the project dependencies explicitly, and transitively, and you can tweak them in ways that you control to suit your own needs and appetite for risk.
Aside to Maveners: the dependency plugin is working much better than it used to, and you can get a print out of the dependency tree with "mvn dependency:tree". This only works with a brand new plugin so make sure that the apache-snapshots repo is in your plugin repositories:
<pluginRepositories>
<pluginRepository>
<id>apache-snapshots</id>
<url>http://people.apache.org/maven-snapshot-repository</url>
</pluginRepository>
</pluginRepositories>
Much more convenient than having to build the whole site and looking in the dependency report, which is what I used to do a lot of.
In the enclosed sandbox archive, there are three poms, each in its own project:
To install the Grails poms you should not need to add any artifacts manually to your local repositiry. There are also a couple of "funnies" (not available in any standard public repo that I could find), which I have included in the "spring-ext" repo (defined in the pom). It should work out of the box if you connected to the internet.
You will need Maven (2.0.*) and Grails (0.5.6) to run the sample application. I'm using Maven 2.0.7. The "grails" and "mvn" launch scripts need to be on your path, and you need to define GRAIL_HOME env variable to run Grails (standard install procedure).
There is also a test project which uses the above poms to manage a web application. I have decided to stick with the Grails directory layout. Graham tells me that nearly all of the "variable" content in web-app/WEB-INF is targeted for removal in Grails 1.0, so I think using the structure layed down by Grails is the best way forward (least likely to be fragile, easily understood by other Grails developers).
To launch from Grails command line
$ cd test
$ mvn package
$ grails run-app
To add additional dependencies to the test project, just add them to the pom and repeat the exercise (or in Eclipse do nothing, see below). Isn't Maven wonderful?
Note that the Grails dependencies have scope=provided in the project pom. That should mean they are in the classpath for Maven and Eclipse, but do not get included in any Maven packaging (if it was implemented).
If you don't use the Maven Eclipse extensions then you can probably work with the Eclipse Maven plugin (otherwise known as maven-eclipse-plugin). Use "mvn eclipse:eclipse" to update the .classpath and refresh and then you should be OK, but won't be able to synchronize automatically with changes in other Eclipse projects.
You will need to do "grails package" from the command line first (once only):
$ cd test
$ grails package
This generates a web.xml for you, and copies and filters over some properties files from grails-app/conf. Apparently the likely long-term outlook is that web.xml will be the only generated file in web-app/WEB-INF (so only one svn:ignore in everyone's scource control system).
In Eclipse you can import the test project. Then you can do Run... and select the "test" launcher form Java Applications. You can debug, and you can change code dynamically, both in the Grails application and in dependent projects.
Here are some known issues or irritations:
The problem is compounded by the fact that the Maven dependency plugin doesn't allow us to exclude provided dependencies (at the moment anyway), so all the Grails dependencies end up in ./lib when you do "mvn package". This would not be comfortable for a Grails developer because they are normally copied from GRAILS_HOME/lib. Ideally this kind of tussle will be resolved before we can say we really have Maven-Grails integration.
For instance we would like to build a WAR file from the Grails project layout. That wouldn't be too difficult to achieve with Ant and Maven. Ideally it would be implemented as a Maven plugin - this is Arnaud's project pretty much, so I hope he makes some progress, but also that he can learn from the experience here.
Other useful lifecycle phases are also missing. For example, tests cannot be driven from Maven in the sample.