diff --git a/WHATSNEW b/WHATSNEW index ea82887d6..3e759b7bd 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -118,9 +118,9 @@ Other changes: * Provide read access to Mkdir.dir. Bugzilla Report 51684. - * has a new attribute performGCOnFailedDelete that may - - when set to true - help resolve some problems with deleting empty - directories on NFS shares. + * and have a new attribute performGCOnFailedDelete + that may - when set to true - help resolve some problems with + deleting empty directories on NFS shares. Bugzilla Report 45807. Changes from Ant 1.8.1 TO Ant 1.8.2 diff --git a/manual/Tasks/delete.html b/manual/Tasks/delete.html index bd0378ffc..635b10f1d 100644 --- a/manual/Tasks/delete.html +++ b/manual/Tasks/delete.html @@ -174,7 +174,7 @@ in Directory-based Tasks, and see the performGCOnFailedDelete - If ant fails to delete a file or directory it will retry the + If Ant fails to delete a file or directory it will retry the operation once. If this flag is set to true it will perform a garbage collection before retrying the delete.
Setting this flag to true is known to resolve some problems on diff --git a/manual/Tasks/move.html b/manual/Tasks/move.html index add618af5..c4f931ad9 100644 --- a/manual/Tasks/move.html +++ b/manual/Tasks/move.html @@ -168,6 +168,19 @@ there is a directory by the same name in todir, the action will fail. on separate machines with clocks being out of sync. since Ant 1.6. + + performGCOnFailedDelete + + If Ant fails to delete a file or directory it will retry the + operation once. If this flag is set to true it will perform a + garbage collection before retrying the delete.
+ Setting this flag to true is known to resolve some problems on + Windows (where it defaults to true) but also for directory trees + residing on an NFS share. + Since Ant 1.8.3 + No, default "true" on + Windows and "true" on any other OS. +

Parameters specified as nested elements

mapper

diff --git a/src/main/org/apache/tools/ant/taskdefs/Move.java b/src/main/org/apache/tools/ant/taskdefs/Move.java index 9b01c4093..99404b920 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Move.java +++ b/src/main/org/apache/tools/ant/taskdefs/Move.java @@ -24,6 +24,7 @@ import java.util.Iterator; import org.apache.tools.ant.Project; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.taskdefs.condition.Os; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.FilterSet; import org.apache.tools.ant.types.FilterSetCollection; @@ -51,6 +52,8 @@ import org.apache.tools.ant.types.FilterSetCollection; */ public class Move extends Copy { + private boolean performGc = Os.isFamily("windows"); + /** * Constructor of object. * This sets the forceOverwrite attribute of the Copy parent class @@ -62,6 +65,19 @@ public class Move extends Copy { setOverwrite(true); } + /** + * Whether to perform a garbage collection before retrying a failed delete. + * + *

This may be required on Windows (where it is set to true by + * default) but also on other operating systems, for example when + * deleting directories from an NFS share.

+ * + * @since Ant 1.8.3 + */ + public void setPerformGcOnFailedDelete(boolean b) { + performGc = b; + } + /** {@inheritDoc}. */ protected void validateAttributes() throws BuildException { if (file != null && file.isDirectory()) { @@ -204,7 +220,7 @@ public class Move extends Copy { if (!moved) { copyFile(fromFile, toFile, filtering, overwrite); - if (!fromFile.delete()) { + if (!getFileUtils().tryHardToDelete(fromFile, performGc)) { throw new BuildException("Unable to delete " + "file " + fromFile.getAbsolutePath()); } @@ -293,7 +309,8 @@ public class Move extends Copy { File f = new File(d, s); if (f.isDirectory()) { deleteDir(f); - } else if (deleteFiles && !(f.delete())) { + } else if (deleteFiles && !getFileUtils().tryHardToDelete(f, + performGc)) { throw new BuildException("Unable to delete file " + f.getAbsolutePath()); } else { throw new BuildException("UNEXPECTED ERROR - The file " @@ -301,7 +318,7 @@ public class Move extends Copy { } } log("Deleting directory " + d.getAbsolutePath(), verbosity); - if (!d.delete()) { + if (!getFileUtils().tryHardToDelete(d, performGc)) { throw new BuildException("Unable to delete directory " + d.getAbsolutePath()); } } @@ -355,7 +372,8 @@ public class Move extends Copy { + " is a no-op.", Project.MSG_VERBOSE); return true; } - if (!(getFileUtils().areSame(sourceFile, destFile) || destFile.delete())) { + if (!(getFileUtils().areSame(sourceFile, destFile) + || getFileUtils().tryHardToDelete(destFile, performGc))) { throw new BuildException("Unable to remove existing file " + destFile); } }