Sunday, July 31, 2011

Keep Your Hands Off of My Whitespace!

We Can Put a Man on the Moon...

Groovy has some awesome XML reading and parsing features that make it a breeze for developers to create new XML strings or to parse existing XML strings.  The XMLSlurper and associated GPathResult classes make it easy to traverse and manipulate the DOM of an XML document/string.  On top of that, the builder support in Groovy (MarkupBuilder, StreamingMarkupBuilder) make it much easier for developers to create structured documents and get essentially built-in commenting for free (since the builder syntax essentially describes the hierarchical document by itself).  With all of these improvements and modern conveniences provided by Groovy regarding XML, you would think that it would be easy to perform the following task:
  1. Read in a file containing XML
  2. Parse the file and find a particular element
  3. Edit the value of said element
  4. Update the file with the changes, preserving the original formatting and namespace(s) of the file.
Good luck.  The builders are great for creating new documents.  While you can use the StreamingMarkupBuilder to handle data read from a file, it does NOT preserve the white-space (and you have to know what additional calls need to be made to preserve any namespaces in the original XML document).  This was a choice made by the implementer, which certainly makes sense for the normal use case of the StreamingMarkupBuilder (creating XML on the fly as a response to a request), where white-space is irrelevant (and takes up precious bytes ;) ).  So, are we just doomed to lose are pretty, human readable formatting when editing XML?  The answer is no.  Luckily, there are some other classes provided by Groovy that will let you do things similar to the normal Groovy XML manipulation approach (slurper, markup builders and GPath).

DOMination

The solution to the problem above is to use the groovy.xml.DOMBuilder and groovy.xml.dom.DOMCategory classes to manipulate XML, while still preserving the formatting/white-space.  Assume that you already have a java.io.File object pointing to an XML file.  You can do the following to manipulate the contents of that file:

    def xml = file.text
    def document = groovy.xml.DOMBuilder.parse(new StringReader(xml)))
    def root = document.documentElement
    use(groovy.xml.dom.DOMCategory) {
        // manipulate the XML here, i.e. root.someElement?.each { it.value = 'new value'}
    }

    def result = groovy.xml.dom.DOMUtil.serialize(root)

    file.withWriter { w ->
        w.write(result)
    }

With 10-15 lines of Groovy code, we have just loaded XML from a file, manipulated its contents, and written it back out to file, while preserving all formatting from the original file.  I wasted about 4 hours trying to figure this out before I stumbled upon the DOMCategory class.  For more information on editing XML using DOMCategory, see the Groovy tutorial on it here.

Wednesday, July 27, 2011

Maven Trick to Rename Grails War

Convention vs. Convention

One of the constant problems with the Grails Maven integration is the competing conventions imposed by the two technologies.  An obvious example of this is the naming convention used for WAR files by the two.  The Maven convention is to use the following when creating a WAR file:
${project.artifactId}-${project.version}.war
When building your Grails application as a WAR file using the Grails command line (i.e. grails prod war), the value of the grails.project.war.file configuration property found in the application's BuildConfig.groovy file is used.  This is obviously not the same convention as the one used by Maven, as described above, and depending on which goals you use with the Grails Maven plugin, you may end up with a WAR named using the Maven convention instead of the Grails convention.  This is because the Grails Maven plugin includes two WAR building Mojos:  GrailsWarMojo and MvnWarMojo.  The former is not tied to any specific phase and is executed if the war goal is executed.  The latter is tied to a phase (package) and therefore is executed automatically if the Grails Maven plugin is included in your POM file and package is specified as a phase to execute (and your project packaging is grails-app).  This Mojo uses the Maven WAR naming convention outlined above.  Therefore, building your Grails application using mvn clean package will result in a WAR named as outlined above.

Cutting Against The Grain

So, now that we know about the two competing conventions, how do we make the Maven build do what we want (that is, how do we make it produce a WAR file named using the Grails naming convention)?  The best solution that I have found is to use the maven-antrun-plugin.  Normally, I don't condone the use of the Ant plugin in Maven, as it is essentially a way to shell out control away from Maven and it is very easy to violate the conventions set for by Maven with this solution.  However, in this case we are trying to break Maven's convention, so the following solution feels acceptable.  To rename the WAR after Maven is done creating it, simply add the following plugin definition to your POM file AFTER the declaration to use the Grails Maven plugin:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
            <execution>
                <id>run-ant-rename-war</id>
                <phase>package</phase>
                <goals>
                    <goal>run</goal>
                </goals>
                <configuration>
                    <tasks>
                        <move file="${project.build.directory}/${project.artifactId}-${project.version}.war" tofile="${project.build.directory}/${project.artifactId}.war" />
                    </tasks>
                </configuration>
            </execution>
        </executions>
</plugin>
This will rename (by moving) the WAR produced with the Maven WAR naming convention to the Grails WAR naming convention, leaving it in the target directory (or whatever you have configured via Maven to be the project.build.directory).

Monday, July 18, 2011

Grails web.xml Generation Magic

The Problem

Grails provides a nice feature in each plugin's descriptor file that allows the plugin to make modifications to the web.xml file created by Grails application that includes the plugin at build time.  This can be done by implementing the doWithWebDescriptor closure in the plugin's descriptor file (see the Grails documentation for more information).  This works fine if you have a limited number of Grails plugins in your application that want to modify the web.xml file or have plugins whose changes to the web.xml file do not require some sort of order.  I recently ran into an issue where we needed to make sure that a custom Grails plugin added a servlet filter to the web.xml that came BEFORE the filters added by the Spring Security plugin.  I did not want to modify the Spring Security plugin to make sure its modifications to the web.xml came after the custom plugin's modifications, nor did I want to assume that the plugins would be installed in a particular order by Grails when building the main application.  

The Solution

After realizing that I could not rely on the order that each plugin's doWithWebDescriptor closure would be called, I decided to use the Grails application's BuildConfig.groovy file to make sure that the web.xml file was modified AFTER all plugins had modified the web.xml file.  This would allow the build to re-organize the servlet filters in the web.xml file to ensure they were in the right order (and would also cover the case where one or more of the filters was not added to the web.xml file -- i.e. this solution would work if one or both of the filters are missing from the generated web.xml file).  The trick is to make use of the grails.war.resources closure in the BuildConfig.groovy file.  This closure is called right before the WAR file is created, ensuring that nothing else will modify the web.xml file.  This takes care of the timing issue.  However, I still needed to write some code to actually modify the order of the servlet filters in the web.xml file.  To do this, I made use of the Groovy shell and binding classes:
    grails.war.resources = { stagingDir, args ->
        ...
        updateWebXml("${stagingDir}/WEB-INF/web.xml")
    }

    private def updateWebXml(webXmlPath) {
        Binding binding = new Binding()
        binding.indentity {
            setVariable("webXmlPath", webXmlPath)
        }

        new GroovyShell(binding).evaluate(new File("ModifyWebXml.groovy")
    }


The updateWebXml method uses the GroovyShell object to execute a Groovy script file, named ModifyWebXml.groovy.  This script uses the XmlSlurper class to read in the existing web.xml file and write out the modified one in its place:


    def webXml = new java.io.File(webXmlPath)
    if(webXml.exists()) {
        def origWebXml = new XmlSlurper().parse(webXml)
        def newWebXml = new groovy.xml.StreamingMarkupBuilder().bind { builder ->
            // Create the new web.xml file from the old one!
        }

        webXml.withWriter { w ->
            w.write(groovy.xml.XmlUtil.serialize(newWebXml))
        }
    }


This solution allowed me to create a script that could re-order the contents of the web.xml file and handle all cases with regards to whether or not the servlet filter entries in question are present or not in the web.xml file used as input.  It is also important to note that this solution can be extended to help in any other situation where you need to make last second modifications to files to be included in the WAR file at build time.

Sunday, July 3, 2011

Bending the Spoon: How to build your Grails application with Maven

It Hurts When I Do That...

When starting a new project a few years back, we made the decision to transition from custom Ant scripts to using Maven as our build manager.  This project contained standard Java libraries (JAR files), OSGi bundles, Grails plugins, and of course, a Grails application (WAR file).  We toyed with the idea of just calling our Ant scripts from Maven, but as engineers, we felt that was a cop-out and defeated the purpose of transitioning to a convention-over-configuration build system such as Maven.  However, in order to achieve the transition to Maven we wanted to be able to completely build our Grails application from Maven without using the Grails command-line (this also meant not taking the easy way out and just using the Maven "antrun" plugin to invoke Grails commands).  Along the way, we had to resolve various issues pertaining to conflicts in conventions between Grails and Maven.  This first article will walk through the Maven support built in to Grails, including the Grails Maven plugin and how we achieved complete Grails/Maven integration for our project.  Subsequent articles will focus on "Mavenizing" your Grails plugins and treating them like any other Maven dependency when building your Grails application.  For the purposes of this article, assume Grails 1.3.7 and Maven 2.2.1 (however, the steps could be applied to any version of Grails and Maven 2.x or 3.x).

Know Your Build Needs

The first step when choosing how to build your Grails application is to spend some time familiarizing yourself with the build support in Grails.  At its core, Grails provides dependency management options in combination with build management and packaging scripts out of the box.  These options can be broken down into the following categories:

  • Simple command line build with few or no external dependencies 
  • Command line build with repository managed dependencies 
  • Command line build with Maven managed dependencies (presence of a POM file) 
  • Maven build (build via Maven using Grails Maven plugin, not the Grails command line)

Build Management

The simple build approach is to let Grails manage everything by placing any required third-party library JAR’s in the /lib folder of your Grails application and using the Grails command line tools to build, package and/or run your application or plugin.  The Grails command line tools make use the Grails Gant scripts, which can be found in the $GRAILS_HOME/scripts folder of your Grails installation.  Building your Grails application or plugin is as simple as running:

grails <environment> war
or
grails package-plugin
where <environment> is one of  "dev", "test", or "prod".  More "advanced" users can make use of the built-in dependency resolution options, as described below.

Dependency Resolution

It is important to realize that Grails uses Ivy to manage the resolution of any dependencies required by plugins or listed in your BuildConfig.groovy file.  Ivy’s role is simply to resolve dependencies (libraries) and get them on the classpath and into your WAR/ZIP file when building your application/plugin via the Grails command line tools.  You can declare dependencies (with Maven-style coordinates) in your application’s BuildConfig.groovy file:


    grails.project.dependency.resolution = {
        ...
        dependencies {
            runtime 'com.mysql:mysql-connector:5.1.5'
        }
    }


You also need to be aware that plugins may include JAR's included in its /lib directory or a Dependencies.groovy file that defines libraries required by the plugin when it is installed in your application (this will be very important later when we discuss "Mavenizing" your Grails plugins).  Finally, Grails also supports pointing Ivy at Maven repositories to resolve dependencies in your BuildConfig.groovy file:


    grails.project.dependency.resolution = {
        repositories {
            mvnRepo "http://repo.grails.org/grails/core"
        }
        ...
    }


This is useful when you need to resolve an internal dependency library when prototyping or building a simple application.  If you are developing in an environment where a POM file full of required dependencies and repositories has been provided for you, you can use the pom true option in your BuildConfig.groovy to make the Grails scripts resolve dependencies from the provided pom.xml file in the root of your project:


    grails.project.dependency.resolution = {
        pom true
    }


This option causes the Grails build scripts to look at your POM file for dependency resolution.

Grails Maven Integration

Up to this point, we have focused on looking at the built-in build support in Grails via the Gant scripts and dependency management mechanisms exposed via the BuildConfig.groovy file.  In addition to its “native” build support, Grails also supports building plugins and applications fully via Maven (with some extra TLC).  The Grails core development team maintains a Grails Maven plugin, which provides Maven goals to perform various Grails related tasks (documentation for the plugin can be found here).  It is important to recognize from the beginning that the Grails Maven plugin is essentially a facade around the Grails Gant scripts.  This means that at the point where the Grails Maven plugin begins to execute a goal, control is transferred from Maven to the Grails scripts themselves.  This detail is probably something that is normally considered part of the "black box" and not given much thought, but it is something that gave us a lot of pain at first.  For instance, because the Grails scripts are essentially being "executed" by the Grails Maven plugin, any libraries that the scripts require to run must be placed on the classpath as runtime dependencies.  This means that you must include dependencies in your POM file that are not actually required by your application at runtime (there have been numerous JIRA issues opened regarding this exact issue in the past).  Because it is a wrapper about the Grails scripts, it is also imperative to make sure that the conventions match.  There are four properties in the BuildConfig.groovy that can be set to cause the Grails scripts to produce artifacts in same directories that Maven expects to find its build artifacts:


    grails.project.class.dir = "target/classes"
    grails.project.test.class.dir = "target/test-classes"
    grails.project.test.reports.dir = "target/test-reports"
    grails.project.war.file = "target/${appName}-${appVersion}.war"


The above settings are the default values included in the BuildConfig.groovy file when you generate your project (the "grails.project.war.file" property will be commented out by default). 

Where To Start

The first decision that we made was to create a POM file that would encapsulate all of the Grails dependencies required by our application.  While the Grails Maven plugin provides a goal to create a POM from their archetype (create-pom), I would recommend that you start by hand-rolling your application or plugin's POM file.  The main reason for this is that the dependencies in Grails 1.3.x are a mess and the archetype produces a somewhat incorrect/out-of-date POM file.  By encapsulating these dependencies in one POM file, it would allow us to easily change the dependency set when and if we decided to upgrade the version of Grails used in our application (we were able to upgrade successfully from 1.2.0 to 1.3.7 using this method with minimal changes to our project's POM file).  This POM file looks something like this:


    <?xml version="1.0" encoding="utf-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>dependencies</groupId>
        <artifactId>grails</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>

        <dependencies>
            <dependency>
                ....
            </dependency>
        </dependencies>

        ...
    </project>


This is just a simple POM that will cause Maven to pull in all of the Grails dependencies required to build our application or plugin.  It is recommended that you leave the version as a SNAPSHOT to make it easier for you to change the version of Grails or the included dependencies without having to redeploy the POM's for your projects that depend on it.  Through some trial and error of attempting to build a simple Grails application WITHOUT any artifacts (i.e. no controllers, domain classes, etc), we arrived at the initial set of dependencies:

  • org.grails:grails-bootstrap:1.3.7
  • org.grails:grails-core:1.3.7
  • org.grails:grails-crud:1.3.7
  • org.grails:grails-gorm:1.3.7
  • org.grails:grails-scripts:1.3.7
  • net.sf.ehcache:ehcache-core:1.7.1
  • hsqldb:hsqldb:1.8.0.10
  • org.slf4j:slf4j-log4j12:1.5.8 (required by Grails scripts to execute)

The majority of the above dependencies will be required by your application a runtime.  As mentioned earlier, a few of these dependencies are merely required for the Grails scripts to execute properly (more on how to resolve this issue in a bit).  Once you have your Grails dependency POM file created, install it into your local Maven .m2 repository:
mvn install
The next step for us was to figure which dependencies we needed to be included in this pom.  To figure this out, we created a simple Grails application using the Grails command-line tools: 
grails create-app test-app
Once we had created the skeleton project, we packaged the application into a WAR file so that we could see which dependencies the Grails build scripts pull into the WAR:
grails prod war
This produces a WAR file in the "target" directory of the Grails application, which we set aside for later comparison to the WAR file produced by Maven.  Next, in order to built a WAR using Maven for the same test project, we created a new POM file for the test project:


    <?xml  version="1.0" encoding="utf-8"?>
    <project  xmlns="http://maven.apache.org/POM/4.0.0"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>my-company</groupId>
        <artifactId>test-app</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>grails-app</packaging>

        <dependencies>
            <dependency>
                <groupId>dependencies</groupId>
                <artifactId>grails</artifactId>
                <version>1.0-SNAPSHOT</version>
                <type>pom</type>
            </dependency>
        </dependencies>

        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>2.4.1</version>
                </plugin>
                <plugin>
                    <groupId>org.grails</groupId>
                    <artifactId>grails-maven-plugin</artifactId>
                    <version>1.3.7</version>
                    <extensions>true</extensions>
                    <configuration>
                        <nonInteractive>true</nonInteractive>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>


Note that if you do not modify the "app.version" property in the application.properties file, Maven will fail the "validate" phase, complaining that the version numbers do not match.  The simple fix for this is to ensure the version number in the application.properties file matches the version number in your POM file (i.e. 1.0-SNAPSHOT).  Also note the special packaging type for this application ("grails-app").  Finally, notice that we added a configuration block for the Grails Maven plugin to execute grails with the "non-interactive" flag, so that we will not be prompted to enter "Y" during the build, if required.  Once we havd created and saved the pom.xml file to the root of the test Grails project, we built the WAR file with Maven by running: 
mvn clean package
This will produce a WAR file in the "target" directory of your Grails project.  The next step was to extract both WAR files (the one produced by Grails command-line tools and the one built with Maven) to temporary directories in order to compare their contents.

We Don't Need No Stinkin' Dependencies!

Once the contents of the two WAR files had been extracted to different directories, we used a merge/diff tool that can compare directories to look for the differences in the WEB-INF/lib folder in the WAR.  The comparison will tell you a few different things:

  • Libraries that appear ONLY in the WAR produced by Maven need to be EXCLUDED from the Grails dependency POM file we created earlier, DELETED from the WAR by using a trick within the BuildConfig.groovy file OR matched up against a dependency of the same name but different version number and reconciled (i.e., Grails will pull in a different version of the Log4j library than Maven).
  • Libraries that appear ONLY in the WAR produced by Grails should be considered to be missing dependencies in the Maven build and need to be ADDED to the Grails dependency POM file we created earlier.
  • The Spring dependencies pulled in by Grails and Maven are identical, but the JAR files are named differently (the Grails versions are named "org.springframework.aop-3.0.5.RELEASE.jar", while the Maven ones are named "spring-aop-3.0.5.RELEASE.jar").  Verify that all the names match (i.e. "aop", "asm", etc).  Follow the above two bullet points for which need to be included/excluded.

To resolve the dependency soup that you see in the WAR's, follow these steps: 

  1. Add any missing dependencies (those that are in the Grails command-line WAR ONLY) to the Grails dependency POM.
  2. Rebuild the WAR file via Maven.
  3. Re-compare the WAR produced by Maven to the WAR produced by Grails.
  4. Look for duplicate libraries that have different version numbers.  Exclude the conflicts from the Grails dependency POM file and add the correct version dependency to the Grails dependency POM file.
  5. Rebuild the WAR file via Maven.
  6.  Add logic to the project's BuildConfig.groovy to delete the non-runtime dependencies pulled in just for executing the Grails scripts (more on how to do this in a bit).
  7. Rebuild the WAR file via Maven.
  8. Re-compare the WAR's -- the included libraries should now be identical.  If not, repeat until they are identical)

To see the Maven dependency tree, use the following Maven command from the root of your Grails project:
mvn dependency:tree -Dverbose=true

This will output the resolved dependency tree for your project and will help you see how the dependency are being transitively resolved and pulled into the WAR file (I recommend piping this to a file, as the output can be rather long).  The "verbose" flag tells the goal to also print out conflicts, so you can see if two dependencies are pulling in different versions of the same dependency and how/why you are ending up with the dependency in the WAR file (based on Maven's conflict resolution strategy).  It is also recommended that you clean up these conflicts by excluding the dependency that you do not want in your dependency tree.  To exclude dependencies in your POM file, find the parent dependency and add the following block to it:


    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions> 


Note that the following artifacts will appear only in the Maven WAR and should NOT be excluded via your Maven dependencies POM file (we will take care of removing these later):

  • org.apache.ant:ant:1.7.1
  • org.apache.ant:ant-launcher:1.7.1
  • org.apache.ant:ant-junit:1.7.1
  • org.apache.ant:ant-nodeps:1.7.1
  • org.apache.ant:ant-trax:1.7.1
  • org.grails:grails-docs:1.3.7
  • org.grails:grails-scripts:1.3.7
  • org.grails:grails-test:1.3.7

As mentioned earlier, because of how the Grails Maven plugin invokes the Grails scripts to build the application, some dependencies are required just to run the underlying Grails scripts (listed above).  These dependencies are not required to deploy your WAR (unless you introduce some specific runtime dependency on them).  To clean out any libraries that you do not want in your WAR (such as the ones listed above), you can make use of the resources closure in the BuildConfig.groovy file:


    grails.war.resources = { stagingDir, args ->
        delete(file:"${stagingDir}/WEB-INF/lib/ant-1.7.1.jar")
    }


This closure gets executed by Grails right before it packages up the WAR file.  It calls the Gant "delete" task to remove the file from the staging directory prior to creating the WAR archive.  Simply add all of the libraries that you do not want included in the WAR (a complete list of what needs to be deleted is listed towards the end of this article).  You can even make it a super-set of files to delete, as it should not cause the build to fail if you reference a file that is sometimes included (this is great if you are using profiles in your Maven build to include different dependencies depending on the selected profile).

Putting It All Together

Once we had identified all of the dependencies that needed to be excluded/deleted, it was just a matter of modifying both the project's BuildConfig.groovy file and the Grails dependency POM we created earlier.  Below is a list of all of the files that need to be deleted in order get the two WAR files in sync:

  • ant-1.7.1.jar
  • ant-junit-1.7.1.jar
  • ant-launcher-1.7.1.jar
  • ant-nodeps-1.7.1.jar
  • ant-trax-1.7.1.jar
  • bcmail-jdk14-138.jar
  • bcprov-jdk14-138.jar
  • core-renderer-R8.jar
  • gant_groovy1.7-1.9.2.jar
  • gpars-0.9.jar
  • grails-docs-1.3.7.jar
  • grails-scripts-1.3.7.jar
  • grails-test-1.3.7.jar
  • itext-2.0.8.jar
  • ivy-2.2.0.jar
  • jsr166y-070108.jar
  • junit-4.8.1.jar
  • radeox-1.0-b2.jar
  • servlet-api-2.5.jar
  • svnkit-1.2.3.5521.jar

After all inclusions and exclusions, the Grails dependency POM file should contain the following dependencies (with exclusions):

  • org:grails:grails-bootstrap:1.3.7
  • org.grails:grails-core:1.3.7
    • Exclusion: commons-beanutils:commons-beanutils
    • Exclusion: commons-collections:commons-collections
    • Exclusion: commons-digester:commons-digester
    • Exclusion: commons-pool:commons-pool
    • Exclusion: javax.persistence:persistence-api
  • org.grails:grails-crud:1.3.7
  • org.grails:grails-gorm:1.3.7
  • org.grails:grails-scripts:1.3.7
  • org.aspectj:aspectjweaver:1.6.8
  • commons-beanutils:commons-beanutils:1.8.0
    • Exclusion: commons-logging:commons-logging
  • commons-codec:commons-codec:1.4
  • commons-collections:commons-collections:3.2.1
  • commons-pool:commons-pool:1.5.5
  • net.sf.ehcache:ehcache-core:1.7.1
  • hsqldb:hsqldb:1.8.0.10
  • jstl:jstl:1.1.2
  • log4j:log4j:1.2.16
  • org.slf4j:slf4j-log4j12:1.5.8
    • Exclusion: log4j:log4j
  • taglibs:standard:1.1.2

We now had a Grails dependency POM that would help us build a WAR of our application using Maven and not the Grails command line.  This POM, in combination with the modifications to BuildConfig.groovy to remove unnecessary dependencies, produced a WAR that contains the exact same runtime dependencies as the Grails command-line tools.  The only other piece that we added to our project POM file to make the results more Maven friendly was the use of the Antrun plugin (ugh, I know) to rename the WAR to drop the version number:


    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.6</version>
        <configuration>
            <tasks>
                <move file="${project.build.directory}/${project.artifactId}-${project.version}.war" tofile="${project.build.directory}/${project.artifactId}.war" />
            </tasks>
        </configuration>
    </plugin>


But Wait...There's More!

Once we had the capability to build a skeleton Grails project with Maven, we began the task of de-conflicting all the other libraries being resolved by Maven when we started adding our code (and other internal libraries) to the project.  Our friend in this battle was the Maven dependency plugin and use of the "tree" goal (described earlier).  This approach worked for us when building against Grails 1.2.0 and 1.3.7.  Early indications are that a similar approach will work with Grails 2.0 (formerly known as 1.4.x).  Keep in mind that the solution presented above does not come without its fair share of hacks (like making use of the BuildConfig.groovy file to remove dependencies injected via Ivy, etc).  However, as long as Grails has support for Ivy built in to its build infrastructure to resolve dependencies, these workarounds will be necessary when attempting to build a Grails application or plugin with Maven.  Finally, I have uploaded the complete sample Grails dependency POM file and the complete sample Grails application POM file:  Grails POM Files.  In my next post, I will take a look at how to get your Grails plugins to be resolved as Maven dependencies when building your application via Maven.  Our solution involved some of the tricks that you have already seen in this post and some custom Maven plugin work.  While our approach ultimately gave us true Maven build support in regards to Grails plugins, my goal is to make the current Grails Maven plugin work out of the box in regards to plugins so that we do not need to create a custom plugin just to help with them, but that is a story for another time.