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

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?

1 Like

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

for example.

Project structure is following.

.
β”œβ”€β”€ build.gradle
β”œβ”€β”€ src
β”‚   └── main
β”‚       β”œβ”€β”€ java
β”‚       β”‚   └── com
β”‚       β”‚       └── sample
β”‚       β”‚           └── model
β”‚       β”‚               └── Person.java
β”‚       β”œβ”€β”€ resources
β”‚       β”‚   └── application.properties
β”‚       └── webapp
β”‚           β”œβ”€β”€ WEB-INF
β”‚           β”‚   └── web.xml
β”‚           └── index.html
└── template
    └── application.properties

And if you wish to change application.properties 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/application.properties')
    // changing file via stage
    def appProperties = file('src/main/resources/application.properties')
    outputs.file appProperties
    outputs.upToDateWhen {
        false
    }
    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()
            .createTemplate(template)
            .make(binding)
        appProperties.write(tmp.toString(), 'UTF-8')
    }
}

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

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

Template file is following.

server.port=$port

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

$ ./gradlew idea

Then application.properties will becomes as follows.

server.port=8080

If you run war task with -PappPort option…

$ ./gradlew war -PappPort=9999

Then the contents of WEB-INF/classes/application.properties file becomes

server.port=9999

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

war {
    expand hostname: 'server.foo.org'
}
1 Like

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.

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']) 
   }
} 
1 Like

Link to stackoverflow post for better quality : https://stackoverflow.com/questions/33464577

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') }
}
1 Like