John is an experienced consultant specialising in Enterprise Java, Web Development, and Open Source technologies, currently based in Sydney, Australia. Well known in the Java community for his many published articles, and as author of Java Power Tools and Jenkins: The Definitive Guide, and founder of the open source Thucydides Automated Acceptance Test Library project, John helps organisations to optimize their Java development processes and infrastructures and provides training and mentoring in agile development, automated testing practices, continuous integration and delivery, and open source technologies in general. John is the CEO of Wakaleo Consulting, and runs several Training Courses on open source Java development tools and best practices. John is a DZone MVB and is not an employee of DZone and has posted 124 posts at DZone. You can read more from them at their website. View Full User Profile

Grails 1.1 and Maven Taken for a Test Drive

03.16.2009
| 5510 views |
  • submit to reddit

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 recently. 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 IDE 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 IDE 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).

From http://weblogs.java.net/blog/johnsmart/

Published at DZone with permission of John Ferguson Smart, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Jason Hatton replied on Mon, 2009/03/16 - 9:11am

Well written article.  Personally Maven has no place in my toolkit.  If it only did dependency management and did that well I would consider it.  Ivy hasn't gotten me excite either but, I would use it first.  To me Grails and Maven are an oxymoron.

Peter Thomas replied on Mon, 2009/03/16 - 2:57pm in response to: Jason Hatton

@jashatton - you may be interested in this article:

Why you should use the Maven Ant Tasks instead of Maven or Ivy

Mladen Girazovski replied on Tue, 2009/03/17 - 8:06am in response to: Peter Thomas

Why you should use the Maven Ant Tasks instead of Maven or Ivy

 Sounds like the author of the article did not unterstand Maven or Ivy...

Kartik Shah replied on Tue, 2009/03/17 - 3:11pm

Really nice article :-)

Wondering Grails Plugin for Maven conflicts with Groovy plugin for Maven.

To use later you have to use src/main/groovy, for Grails files are groovy so what structure should they go. 

 

Peter Thomas replied on Tue, 2009/03/17 - 5:57pm in response to: Mladen Girazovski

Sounds like the author of the article did not unterstand Maven or Ivy...

Sounds like the author of this comment did not even read the article :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.