-
Improvement
-
Resolution: Fixed
-
Major
-
None
-
Microsoft Windows
Please enhance the hudson.Util.deleteContentsRecursive method to:
- delete everything it can
- try several times to delete everything
- only throw an exception if it can't delete everything (listing everything that it can't delete)
Reasoning...
Unlike unix, the Microsoft Windows OS does not allow a file to be deleted if something has that file open. This causes delete operations to fail.
Furthermore, most installations of Windows have software that monitors the filesystem for activity and then inspects the contents of recently added/removed files (which means that it'll lock them, albeit temporarily), e.g. the Windows Search service & anti-virus software to name but two (but Windows Vista & Windows 7 seem to have additional complications)
This means that builds which rely on cleaning a workspace before they start will sometimes fail (claiming that they couldn't delete everything because a file was locked), resulting in a build failing with the following output:
Started by an SCM change Building remotely on jenkinsslave27 in workspace C:\hudsonSlave\workspace\MyProject Purging workspace... hudson.util.IOException2: remote file operation failed: C:\hudsonSlave\workspace\MyProject at hudson.remoting.Channel@6f0564d7:jenkinsslave27 at hudson.FilePath.act(FilePath.java:835) at hudson.FilePath.act(FilePath.java:821) at hudson.plugins.accurev.AccurevSCM.checkout(AccurevSCM.java:331) at hudson.model.AbstractProject.checkout(AbstractProject.java:1218) at hudson.model.AbstractBuild$AbstractRunner.checkout(AbstractBuild.java:586) at hudson.model.AbstractBuild$AbstractRunner.run(AbstractBuild.java:475) at hudson.model.Run.run(Run.java:1434) at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46) at hudson.model.ResourceController.execute(ResourceController.java:88) at hudson.model.Executor.run(Executor.java:239) Caused by: java.io.IOException: Unable to delete C:\hudsonSlave\workspace\MyProject\...\src\...\foo - files in dir: [C:\hudsonSlave\workspace\MyProject\...\src\...\foo\bar] at hudson.Util.deleteFile(Util.java:236) at hudson.Util.deleteRecursive(Util.java:287) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.Util.deleteRecursive(Util.java:278) at hudson.Util.deleteContentsRecursive(Util.java:198) at hudson.plugins.accurev.PurgeWorkspaceContents.invoke(PurgeWorkspaceContents.java:28) at hudson.plugins.accurev.PurgeWorkspaceContents.invoke(PurgeWorkspaceContents.java:11) at hudson.FilePath$FileCallableWrapper.call(FilePath.java:2161) at hudson.remoting.UserRequest.perform(UserRequest.java:118) at hudson.remoting.UserRequest.perform(UserRequest.java:48) at hudson.remoting.Request$2.run(Request.java:287) at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at hudson.remoting.Engine$1$1.run(Engine.java:60) at java.lang.Thread.run(Unknown Source)
What's needed is a retry mechanism. i.e. the equivalent of using Ant's <retry><delete file="foo"/></retry>, but with a (small) delay between attempts (and maybe a call to the garbage collector, just in case the process holding the file open is the build slave process itself).
- is duplicated by
-
JENKINS-10905 Deleting previous project files regularly fails the build
-
- Resolved
-
-
JENKINS-24481 Could not deleting files/folder in workspace
-
- Resolved
-
-
JENKINS-14808 IOException: Unable to delete <FileName> on Windows Slaves
-
- Resolved
-
-
JENKINS-3053 Unable to delete SCM files
-
- Resolved
-
- is related to
-
JENKINS-15852 Unable to delete workspace
-
- Open
-
-
JENKINS-10905 Deleting previous project files regularly fails the build
-
- Resolved
-
-
JENKINS-3053 Unable to delete SCM files
-
- Resolved
-
-
JENKINS-17995 Jenkins produces DirectoryNotEmptyException when attempting to delete large directories
-
- Resolved
-
[JENKINS-15331] Workaround Windows unpredictable file locking in Util.deleteContentsRecursive
Link |
New:
This issue is related to |
Status | Original: Open [ 1 ] | New: In Progress [ 3 ] |
Attachment | New: 0001-JENKINS-15331.patch [ 22814 ] |
Link |
New:
This issue is related to |
Note: This file locking behavior also causes non-Jenkins issues, e.g. deleting multiple folders using Windows explorer will sometimes leave one (usually empty) folder behind, and even a simple "RD /S /Q MyFolder" will sometimes fail to delete the folder on its first attempt. In these cases, simply retrying the operation will succeed. Personally, I think it's a Windows "feature".
As a workaround, I've wrapped most of my calls to Ant's <delete> task in <retry>, and this has eliminated this problem from any of my builds that manage to start BUT this doesn't help if Jenkins doesn't get as far as running my builds.
e.g. I'm using the accurev plugin for my SCM and it cleans the working directory before it grabs the source - I typically get about a 1% failure rate at this stage. Whilst 1% is not a blocking issue, it's not reliable, which is not what one wants from a build system.
Personally, I've found that excluding the build areas from Search & anti-virus helps reduce the problem, but it is insufficient to stop these failures completely (at least on Windows 7) - something, somewhere, will still lock files, sometimes, but any investigation (after the build has failed failed) shows that no process has the file "open".