Pre-existing zip/ear/jar/war filter

I have an .ear file that needs to be deployed. However, that .ear has embedded config that needs to change on a per environment basis.

Whilst I would like to filter inside the zip, I haven’t found a way to achieve this. Instead I came up with the following:

import org.apache.tools.ant.filters.ReplaceTokens
   task deployEar << {
      copy{
    from zipTree ("/path/to/my.ear")
    into "/path/to/exploded"
    filesMatching("/path/to/exploded/connections.xml"){
      filter(ReplaceTokens, tokens: [
          "oldurl.1.com" : "newurl.1.com",
          "oldurl.2.com" : "newurl.2.com",
          "oldurl.3.com" : "newurl.3.com",
        ])
    }
  }
      ant.zip(destfile: "/path/to/deploy/my.ear", basedir: "/path/to/exploded")
      // deployment logic here
}

Unfortunately this doesn’t work, and isn’t very elegant either. Any help would be greatly received.

Ahhaa, it turns out I was expecting too much from the task. I now realise I need the token wrapped with @…@, and similarly if I use expand ${…}.

I guess this changes my question to how can I achieve this in a groovy way?

ant.replace (file: "/path/to/exploded/connections.xml", token: "oldurl.1.com", value: "newurl.1.com")

The line above works, but makes the build file extremely messy when doing more than a few replaces.

This might work:

import org.apache.tools.ant.filters.ReplaceTokens
task deployEar << {
  copy{
    from zipTree ("/path/to/my.ear")
    into "/path/to/exploded"
    filesMatching("/path/to/exploded/connections.xml"){
      filter(ReplaceTokens, tokens: [
          "oldurl.1.com" : "newurl.1.com",
          "oldurl.2.com" : "newurl.2.com",
          "oldurl.3.com" : "newurl.3.com",
        ], startToken: "", endToken: "")
    }
  }
  ant.zip(destfile: "/path/to/deploy/my.ear", basedir: "/path/to/exploded")
  // deployment logic here
}

Unfortunately I tried that and it didn’t work. I’ve settled with the slightly ugly but functional solution below.

ant.unzip(src: "/path/to/my.ear", dest: "/path/to/exploded")
ant.replace (file: "/path/to/exploded/connections.xml", token: "oldurl.1.com", value: "newurl.1.com")
ant.replace (file: "/path/to/exploded/connections.xml", token: "oldurl.2.com", value: "newurl.2.com")
ant.replace (file: "/path/to/exploded/connections.xml", token: "oldurl.3.com", value: "newurl.3.com")
ant.zip (destfile: "/path/to/deploy/my.ear", basedir: "/path/to/exploded")
ant.delete (dir: "/path/to/exploded")

After revisiting this issue I decided to go the programmatic root. I have shared what decided as my solution on my blog for anyone interested:

Gradle Filtering Archives

I believe Luke’s solution should work. I’ve used a nearly identical configuration in a build. I think the problem is the property we need to set is ‘beginToken’ not ‘startToken’.