February 4, 2011

Grails Goodness: One WAR to Rule Them All (Part 3)

In part 1 we learned how we can define environment specific configuration in our application code. In part 2 we moved some of the configuration outside the application code and into external configuration files. The goal is to have a single WAR file that can be deployed to several environments and still contains configuration properties per environment. We use $ grails war to create the WAR file and if we deploy this WAR file to for example Tomcat we see the display name of our Grails application is set to /sample-production-0.1:

The name consists of our application name, environment used to create the WAR file (by default Grails uses production when creating a WAR file) and the application version. Grails automatically sets this value when we package the application as WAR file. It can be confusing to see the environment production in the display name, so we set the value of the display name to a another value.

We first get the template web.xml Grails uses and set the value of display-name to a new value.

$ grails install-templates

We open src/templates/war/web.xml and look for the display-name element. The value is /@grails.project.key@. Grails uses the ANT replace task when building the WAR file to replace @grails.project.key@ with application name, environment and application version. We want a custom value so we change the display-name:


<display-name>Sample Application :: @grails.app.name.version@</display-name>


We use the @...@ syntax, because we will use the ANT replace task, to add the application name and version to the generated web.xml. Next we create scripts/_Events.groovy and listen to the WebXmlStart event. Here we get a hold on the web.xml and use the ANT replace task to inject the application name and version.

// File: scripts/_Events.groovy
eventWebXmlStart = { webXmlFile ->
    ant.echo message: "Change display-name for web.xml"
    def tmpWebXmlFile = new File(projectWorkDir, webXmlFile)
    ant.replace(file: tmpWebXmlFile, token: "@grails.app.name.version@",
                value: "${grailsAppName}-${grailsAppVersion}")

We are ready to create the WAR file ($ grails war) and deploy it to our Tomcat instance. If we look at the display name we see our custom display name Sample Application:: sample-0.1: