How do I just change the contents of a resource file in the war plugin?

(Mike Smithson) #1

I have an xml file where I want to just change a single line in the file and nothing else. I am able to change the content of the file but I can’t seem to figure out how to preserve that change while keeping the file name and location the same. Any ideas?

(Shinya Mochida) #2

How about using Groovy’s GStringTemplateEngine. (see detail)

for example.

Project structure is following.

├── build.gradle
├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── sample
│       │           └── model
│       │               └──
│       ├── resources
│       │   └──
│       └── webapp
│           ├── WEB-INF
│           │   └── web.xml
│           └── index.html
└── template

And if you wish to change file, when creating war file.

build.gradle file is as following.

// declaration of plugins/dependencies/repositories

import groovy.text.GStringTemplateEngine

task prepareApplicationProperties {
    // load template file
    def template = file('template/')
    // changing file via stage
    def appProperties = file('src/main/resources/')
    outputs.file appProperties
    outputs.upToDateWhen {
    doLast {
         // change contents via cli options
        def env = project.hasProperty('appPort') ? appPort : 'dev'
        def port = env == 'dev' ? 8080 : appPort as int
        def binding = [port: port]
        // change file contents
        def tmp = new GStringTemplateEngine()
        appProperties.write(tmp.toString(), 'UTF-8')

tasks.idea.dependsOn 'prepareApplicationProperties'
tasks.war.dependsOn 'prepareApplicationProperties'

This script generates file before idea task(if you use eclipse change idea to eclipse) and war task.

Template file is following.


if you run idea task (thus this is develop environment), without -PappPort option…

$ ./gradlew idea

Then will becomes as follows.


If you run war task with -PappPort option…

$ ./gradlew war -PappPort=9999

Then the contents of WEB-INF/classes/ file becomes


(Mark Vieira) #3

You can leverage Groovy’s SimpleTemplateEngine by just passing a map to any Copy task’s expand() method.

war {
    expand hostname: ''

(Mike Smithson) #4

Unfortunately, we cannot use templating in the file that needs to have its content replaced, we would need to do some sort of replace(). I think it boils down to my limited knowledge of Gradle and Groovy.

(Lance Java) #5

Possibly easiest to use with(CopySpec) in either the war or processResources tasks (depending on the target folder)

war {
   with copySpec {
      from 'src/template/webapp' 
      filter(ReplaceTokens, tokens: ['someToken':'someValue']) 
processResources {
   with copySpec {
      from 'src/template/resources' 
      filter(ReplaceTokens, tokens: ['someToken':'someValue']) 

(Vic Seedoubleyew) #6

Link to stackoverflow post for better quality :

To complement Lance_Java's answer, I found this idiom more simple if there’s only one value you are looking to change:

task generateSources(type: Copy) {
    from 'src/replaceme/java'
    into "$buildDir/generated-src"
    filter { line -> line.replaceAll('xxx', 'aaa') }