Skip to main content

Grails 1.1 and Maven taken for a test drive

Posted by johnsmart on March 11, 2009 at 7:17 PM PDT

Grails is a great little framework - like any framework, you'll need to learn how it works before becoming really productive, and you have to beware of too much hot-shot Groovy code making the application hard to maintain, but I for one am finding it a real boost.

However, personally, I can't live without my Maven dependency management. Yes, I know, Ivy bla bla bla, but Ivy IDE integration sucks. So I was really looking forward to Grails 1.1 because of its promised Maven support.

As people will no doubt be aware, Grails 1.1 came out earlier this week. So I thought I'd take the Maven support for a spin.

Your starting point for any Maven/Grails integration work should be the Grails documentation, or more precisely, the Grails Maven Integration page. Here all will be revealed.

Well, almost all. First of all, you do need to configure your settings.xml file as instructed in the documentation:


<settings>
  ...
  <pluginGroups>
    <pluginGroup>org.grails</pluginGroup>
  </pluginGroups>
</settings>

From there on, it's slightly simpler than the documentation suggests - you don't need to much about with snapshot repositories or specific versions of the archetype plugin. In fact, all you really need is something like this:

$ mvn archetype:generate -DarchetypeGroupId=org.grails \
 -DarchetypeArtifactId=grails-maven-archetype  -DarchetypeVersion=1.0 \
 -DarchetypeRepository=http://repository.codehaus.org -DgroupId=com.acme \
 -DartifactId=killerapp

Then cd into your new project directory, and initialize the Grails project structure

$ mvn initialize

And lo-and-behold! A fully armed and operational Grails project!

I can run

mvn grails:create-domain-class

or
grails create-domain-class

from the command line, with the same effect. Maven has no added value when creating Grails classes, so I'd probably prefer the latter.

However, the real reason I was so keen on integrating Grails with Maven was to benefit from the Maven Dependency Management features.

I open up the pom.xml. There are already a lot of dependencies, but Hamcrest isn't one of them. So I add it at the end of the dependencies:


<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.5<version>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.1</version>
</dependency>

No big deal, pretty standard Maven stuff. Now I add some Hamcrest asserts to my Grails unit tests:

    void testShouldCheckForMandatoryName() {
        mockDomain(Listing)
        def listing = new Listing(name:null,...)
        assertFalse "validation should have failed", listing.validate()
        assertEquals "nullable", listing.errors.name
    }

becomes
    import static org.junit.Assert.*;
    import static org.hamcrest.Matchers.*;
    ...
    void testShouldCheckForMandatoryName() {
    mockDomain(Listing)
        def listing = new Listing(name:null,...)
        assertThat listing.validate(), is(false)
        assertThat listing.errors.name, is("nullable")
    }

Much nicer, aye? By the way, if you are using integration tests to test your field validation in Grails 1.1, don't - use mockDomain instead. This method basically mocks out all of the dynamic domain methods in your domain class (save(), load(), find(), validate(), and so on), so that you can test your validation rules (even "unique"!) to your heart's content. It will perform basic saves, loads, and deletes, using an in-memory list behind the scenes (no database required!). You can learn about the mockDomain() function and other cool new ways of testing in Grails 1.1 at http://www.grails.org/Testing+Plugin.

At this point, as you would expect, running grails test-app from the command line will no longer cut it. To get your dependencies taken into account, you need to run mvn test. Which is the same thing, except that it throws your dependencies into the mix as well.

So how do the IDEs fare with all this? Netbeans copes poorly. It can see that it's a Grails project, but apparently doesn't know about Maven/Grails integration. And you can't force it to open the project as a Maven project, and then tell it about the Grails structure afterwards. So you can add all the dependencies you like to the pom.xml file, they still won't show up in the auto-completion, and Netbeans will complain about missing classes and packages all over the place. Not cool at all.

IntelliJ copes much better. I imported the project as a Maven project, and it proposed to add the Grails facet automatically. It could find all of the Maven dependencies just fine. Running the tests that use the Hamcrest dependencies works fine - in fact, it's excessively fast from within IntelliJ (much faster that from the command line).

"Probably the best training course I've been on."..."Not just how to write Java code but the 'business end' - how to build, test, deploy, manage and monitor"..."One of the best and most useful courses I have attended. And they didn't even try to sell me anything!" - Get up to scratch with the latest in Java tools and best practices! Sign up on the 2009 season of the Java Power Tools Bootcamps.

Comments

Hei! Thanks for the article! Do you know whether it's possible to create Grails plugins with Maven? I love Grails, but I'm no fan of their usage of svn as a repository.