Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Update An Existing War/Jar/Zip File Using Gradle?

I need to make a copy of an existing war file and update an xml file within it. My thoughts on how to do this are:

  • Extract file from existing war
  • Replace String in file
  • Copy war
  • Add modified file back to copied war

I can do the first 3 steps with Gradle but I can only work out how to do the last step with Ant.

task updateWar() << {
    def originalWar = file("deploy/mywar.war")
    def outputDir = file("deploy")
    def wars = [ "war1", "war2" ]
    wars.each() { warFile ->        
        delete "deploy/WEB-INF/ejb.xml"
        copy {
            //Step 1
            from(zipTree(originalWar)) {
                include 'WEB-INF/ejb.xml'
            }
            into outputDir
            //Step 2
            filter{
                String line -> line.replaceAll("<value>OriginalText</value>",
                        "<value>UpdatedText</value>")
            }
        }
        //Step 3
        copy {
            from outputDir
            into outputDir
            include 'mywar.war'
            rename 'mywar.war',"${warFile}.war"
        }       
        //Step 4
        ant.jar(update: "true", destfile: deploy/${warFile}.war") {
            fileset(dir: deploy", includes: 'WEB-INF/**')
        }
    }
}

Ideally there would be a filter option that allowed me to modify the specified file when I was copying but I haven't worked that out yet.

How do you do this effectively in Gradle without falling back to Ant? Is even a groovy gradle way to do it in one step?

Edit: I have got closer. A Zip task using a ziptree from the original war was the first key step. The filesMatching combined with the filter was the secret sauce! However, I can't use this in a loop like I can the copy method so I'm still stuck :(

task updateWar(type: Zip) {
    def originalWar = file("deploy/mywar.war")
    def outputDir = file("deploy")
    archiveName = "war2.war"
    destinationDir = outputDir
    from (zipTree(originalWar),{
        filesMatching("WEB-INF/ejb.xml") {
            filter{
                String line -> line.replaceAll("<value>OriginalText</value>",
                        "<value>UpdatedText</value>")
            }
        }
    })
}
like image 595
opticyclic Avatar asked Jan 27 '15 16:01

opticyclic


1 Answers

Assuming you just want to replace the original file within the war with one in the res folder, here is how to do it:

task updateWar(type: Zip) {
    def originalWar = file("deploy/mywar.war")

    archiveBaseName = 'mywar'
    archiveExtension = 'war'

    from(zipTree(originalWar)) {
        // Remove the original ejb.xml if it exists
        exclude("**/WEB-INF/ejb.xml")
    }

    // Include our own ejb.xml
    from('res/ejb.xml') {
        into('WEB-INF/')
    }
}
like image 99
smac89 Avatar answered Sep 17 '22 15:09

smac89