Search code examples
gradlegrailsgroovy

Grails "war" invocation not passing extra properties to Gradle


When invoking the "grails war" command, the grails.env property is passed to Gradle, but any other property that I define with -D is not being passed.

I have verified that Gradle will get the properties and I can print them with a command like "gradle -Dgrails.env=development -Dfoo.bar=blech"

Invoking grails with this command:

grails -Dgrails.env=development -Dfoo.bar=blech war build.gradle:

ext {
    currentBuildEnvironment = System.properties['grails.env']
    println "Current build environment is ${currentBuildEnvironment}"
    fooBar = System.properties['foo.bar']
    println "fooBar: ${fooBar}"
}

This properly prints "development" for currentBuildEnvironment, but prints null for fooBar.


Solution

  • By default, you not allowed to pass custom properties to grails command.

    From Grails Command Line documentation:

    The grails command is a front to a gradle invocation, because of this there can be unexpected side-effects. For example, when executing grails -Dapp.foo=bar run-app the app.foo system property won’t be available to your application. This is because bootRun in your build.gradle configures the system properties. To make this work you can simply append all System.properties to bootRun in build.gradle like:

    bootRun{
       systemProperties System.properties // Please note not to use '=', because this will > override all configured systemProperties. This will append them.
    }
    

    And use in your script for fetching any custom properties:

    ext {
        fooBar = bootRun.systemProperties['foo.bar']
        println "fooBar: ${fooBar}"
    }
    

    Also, you can pass a limited set of properties based on prefix:

    bootRun{
        systemProperties System.properties.inject([:]){acc,item-> item.key.startsWith('foo.')?acc << [(item.key.substring('foo.'.length())):item.value]:acc }
    }
    

    And just fetch property without prefix:

    ext {
        fooBar = bootRun.systemProperties['bar']
        println "fooBar: ${fooBar}"
    }
    

    You can play with passing properties in bootRun section:

    systemProperties System.properties.inject([:]){acc,item-> item.key.startsWith('foo.')?acc << [(item.key):item.value]:acc }
    

    will have all properties starting from 'foo' and with suffix:

    bootRun.systemProperties['foo.bar']