Excluding files from a WAR with Grails – the right way

Posted by: on Jan 21, 2009 | 12 Comments

I have seen people try to remove JARs shipped with Grails from their WAR by completely redefining their list of grails dependencies in Config.groovy. This is understandable because on the surface there seems to be no way to “exclude” just one or two JARs as in Config.groovy you do not have access to the DEFAULT_DEPS list.

However, I had cause to do this last night to make a new Mor.ph deployment plugin that actually works, and I knew there was a better way.

If you have an application that needs to exclude one or more resources, you can do this in Config.groovy just by supplying a closure that uses Ant calls to delete the resources, in the grails.war.resources property:

// Remove the JDBC jar before the war is bundled
grails.war.resources = { stagingDir ->
  delete(file:"${stagingDir}/WEB-INF/lib/jdbc2_0-stdext.jar")
}

However if you are writing a plugin, this option is not available to you. Never fear – Grails scripting events to the rescue.

All you need to do is add a _Events.groovy file to your plugin in the ./scripts folder, and add code like this:

// Remove the JDBC jar before the war is bundled
eventWarStart = { warName ->
    if (grailsEnv == "production") {
        println "Removing JDBC 2 Extensions JAR"
        Ant.delete( 
           file:"${stagingDir}/WEB-INF/lib/jdbc2_0-stdext.jar")
    }
}

This WarStart event is called after the whole staging area has been prepared, just before zipping it up into a .war. So you can do whatever you like to the tree using Ant!

I never thought I’d enjoy the start of a war…

12 Comments

  1. Bob Herrmann
    January 22, 2009

    That last sentence was too funny.

  2. Stefan
    January 22, 2009

    Marc, thanks a lot for this. The neat thing with Grails is, if you got a working solution for something, there’s always one out there with a more elegant one…

  3. markatharvest
    January 26, 2009

    Marc, this is neat solution, I was doing it manually early, and it was a pain!!
    Btw, about cloud hosting blog, I do use Morph for solution, but looking something better, a server which can be used host many websites at once for saving costs and improving scalability

  4. robpatrick
    March 18, 2009

    Great post Marc, very useful.

    I think I’m right in saying this has been replaced by eventCreateWarStart in grails 1.1. The event now passes a warName and stagingDir.

  5. stephen pasco
    December 9, 2009

    Hi Marc, Thanks for this great tip. I’ve tried this with 1.2-m4 and it doesn’t seem to work. I’ve placed ‘grails.war.resources’ at the top of my config.groovy, should it be elsewhere?

  6. stephen pasco
    December 10, 2009

    I figured this out. ‘grails.war.resources’ now belongs w/in the BuildConfig.groovy file with grails 1.2.xx.

  7. Reiner Saddey
    March 26, 2010

    Hi Marc,

    it appears as though with Grails configuration tasks appear to be somewhat of a moving target – your code no longer works with Grails 1.2.1.

    Using Grails 1.2.1, both the event name and its parameters need to be changed within _Events.groovy:

    eventCreateWarStart = { warName, stagingDir ->
    if (grailsEnv == “production”) {

  8. Lucas Teixeira
    June 7, 2010

    Just to update it out!

    In grails 1.3, we should use BuildConfig.groovy to declare te ‘grails.war.resources’ closure.

    Thanks Marc!

  9. tony
    March 28, 2011

    and deleting many files

    grails.war.resources = { stagingDir ->
    delete{
    fileset(dir: “${stagingDir}/reports/”, includes : ‘*.jrxml’ )
    }
    }

    and for plugins

    eventWarStart = { warName ->
    if (grailsEnv == “production”) {
    Ant.delete{
    fileset(dir: “${stagingDir}/reports/”, includes : ‘*.jrxml’ )
    }
    }
    }

  10. Le Do Hoang Long
    May 24, 2011

    Good tip, thank Marc & Lucas :)

  11. Chandan Luthra
    November 16, 2011

    Very nice tip….I only invested 2 mins in googleing and completed 2 hour task :)

  12. Nick Hammond
    November 23, 2011

    Just note that the ‘Ant’ should be ‘ant’ for grails 1.3.x