Gradle deleting files from its most recent copy task when it loads?

I am experiencing some gradle weirdness and need help. I am running an ‘explodedWar’ task which does what I expect it to do (extracts the war to my build/webapp dir.) I configured the war task to use a specific web.xml file which you can see below. The problem comes when I try to run any task (e.g. sayHello) afterwards from the command line. The web.xml file residing under build/webapp/WEB-INF gets deleted along with class files under build/webapp/WEB-INF/classes. At first I thought it had something to do with some sort of task clean up or dependency. Then I tried running a few tasks together sequentially from the command line: gradle clean explodedWar sayHello.

Performing that command did NOT delete the files. The NEXT command did (e.g. gradle sayHello) leading me to believe that gradle is doing something like a ‘sync’ when it loads to run a task. Is this a bug?

I am using Gradle 1.8

task explodedWar(type: Copy, dependsOn: war) {

into “$buildDir/webapp”

with war }

war {

doLast {

println ‘Setting my web.xml’

webXml = file(‘build/resources/main/web.xml’)

} }

task sayHello << {

println ‘say Hello to my little friend!’ }

Thanks, Matt

For one thing, ‘war.webXml’ needs to be configured in the configuration phase, rather than after the task has run (i.e. the ‘doLast {}’ needs to be removed). If that alone doesn’t help, another thing you could try is to replace ‘with war’ with ‘from zipTree(war.outputs.files.singleFile)’.


Thanks for the quick response. The reason why I specified ‘doLast’ is because the web.xml file gets processed by the ‘processResources’ task, where it gets filtered, then landing in ‘build/resources/main’. If I were to set it during the configuration phase, wouldn’t I be setting it to a file that doesn’t exist?


If I were to set it during the configuration phase, wouldn’t I be setting it to a file that doesn’t exist?

It’s common to do that, and it’s not a problem. You’d only defer configuration if you couldn’t tell the file path upfront. And in that case you’d use ‘doFirst’, as ‘doLast’ will only execute after the War has been created.


I tried your proposed solution, and unfortunately it didn’t work. Files are still being delete with a subsequent task run. I’ve attached a link to the debug output of that subsequent command:

The output does show the files being deleted. However, I can’t tell why:

08:42:46.000 [DEBUG] [org.gradle.api.internal.file.copy.DeleteActionImpl] Deleting /usr/local/singlewire/InformaCast/webapp/WEB-INF/web.xml 08:42:46.001 [DEBUG] [org.gradle.api.internal.file.copy.DeleteActionImpl] Deleting /usr/local/singlewire/InformaCast/webapp/WEB-INF/classes/com 08:42:46.225 [DEBUG] [org.gradle.api.internal.file.copy.DeleteActionImpl] Deleting /usr/local/singlewire/InformaCast/webapp/WEB-INF/classes/ 08:42:46.227 [DEBUG] [org.gradle.api.internal.file.copy.DeleteActionImpl] Deleting /usr/local/singlewire/InformaCast/webapp/WEB-INF/classes/deploy.jar

I’d need a way to reproduce this. Chances are that something’s wrong with your build script.

You’re right Peter. I put together a small “dummy” webapp with roughly the same build script logic, and I didn’t see these files being deleted. I’ll have to break down my original build script until I find the culprit.

Thanks, Matt


I found the problem. I was a bit overzealous with some cleanup tasks, namely the following:

task cleanWebInf (type: Delete, dependsOn: buildSettings) {

def myCleaningList = [

ovaHome + ‘/webapp/WEB-INF/web.xml’,

ovaHome + ‘/webapp/WEB-INF/classes/com’,

ovaHome + ‘/webapp/WEB-INF/classes/’,

ovaHome + ‘/webapp/WEB-INF/classes/deploy.jar’


myCleaningList.each { delete it } }

This must run during configuration time, regardless of the tasks called to execute, which resulted in the deletions I was seeing. Scary, because I didn’t see the ‘cleanWebInf’ task name displayed when running my builds.


I don’t think this needs to or should be run at configuration time. And if it had to, you wouldn’t declare a task for it.