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)’.

Peter,

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?

Matt

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.

Peter,

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:

https://dl.dropboxusercontent.com/u/27167523/gradleDebug.txt

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/log4j.properties 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

Peter,

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/log4j.properties’,

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.

Matt

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.