git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@703151 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -404,6 +404,12 @@ Other changes: | |||||
| * <ftp> now supports selectors for remote directories as well. | * <ftp> now supports selectors for remote directories as well. | ||||
| Bugzilla Report 44726. | Bugzilla Report 44726. | ||||
| * In some cases Ant fails to rename files if the source or target | |||||
| file has just recently been closed on Windows. It will now try to | |||||
| delete the offending file once again after giving the Java VM time | |||||
| to really close the file. | |||||
| Bugzilla Report 45960. | |||||
| Changes from Ant 1.7.0 TO Ant 1.7.1 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
| ============================================= | ============================================= | ||||
| @@ -57,6 +57,7 @@ import org.apache.tools.ant.types.selectors.FilenameSelector; | |||||
| import org.apache.tools.ant.types.selectors.MajoritySelector; | import org.apache.tools.ant.types.selectors.MajoritySelector; | ||||
| import org.apache.tools.ant.types.selectors.ContainsRegexpSelector; | import org.apache.tools.ant.types.selectors.ContainsRegexpSelector; | ||||
| import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; | import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; | ||||
| import org.apache.tools.ant.util.FileUtils; | |||||
| import org.apache.tools.ant.util.SymbolicLinkUtils; | import org.apache.tools.ant.util.SymbolicLinkUtils; | ||||
| /** | /** | ||||
| @@ -74,7 +75,6 @@ import org.apache.tools.ant.util.SymbolicLinkUtils; | |||||
| * @ant.task category="filesystem" | * @ant.task category="filesystem" | ||||
| */ | */ | ||||
| public class Delete extends MatchingTask { | public class Delete extends MatchingTask { | ||||
| private static final int DELETE_RETRY_SLEEP_MILLIS = 10; | |||||
| private static final ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem()); | private static final ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem()); | ||||
| private static final ResourceSelector EXISTS = new Exists(); | private static final ResourceSelector EXISTS = new Exists(); | ||||
| @@ -114,6 +114,7 @@ public class Delete extends MatchingTask { | |||||
| private boolean failonerror = true; | private boolean failonerror = true; | ||||
| private boolean deleteOnExit = false; | private boolean deleteOnExit = false; | ||||
| private Resources rcs = null; | private Resources rcs = null; | ||||
| private static FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||||
| private static SymbolicLinkUtils SYMLINK_UTILS = | private static SymbolicLinkUtils SYMLINK_UTILS = | ||||
| SymbolicLinkUtils.getSymbolicLinkUtils(); | SymbolicLinkUtils.getSymbolicLinkUtils(); | ||||
| @@ -659,16 +660,7 @@ public class Delete extends MatchingTask { | |||||
| * wait a little and try again. | * wait a little and try again. | ||||
| */ | */ | ||||
| private boolean delete(File f) { | private boolean delete(File f) { | ||||
| if (!f.delete()) { | |||||
| if (Os.isFamily("windows")) { | |||||
| System.gc(); | |||||
| } | |||||
| try { | |||||
| Thread.sleep(DELETE_RETRY_SLEEP_MILLIS); | |||||
| } catch (InterruptedException ex) { | |||||
| // Ignore Exception | |||||
| } | |||||
| if (!f.delete()) { | |||||
| if (!FILE_UTILS.tryHardToDelete(f)) { | |||||
| if (deleteOnExit) { | if (deleteOnExit) { | ||||
| int level = quiet ? Project.MSG_VERBOSE : Project.MSG_INFO; | int level = quiet ? Project.MSG_VERBOSE : Project.MSG_INFO; | ||||
| log("Failed to delete " + f + ", calling deleteOnExit." | log("Failed to delete " + f + ", calling deleteOnExit." | ||||
| @@ -678,7 +670,6 @@ public class Delete extends MatchingTask { | |||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | |||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -54,6 +54,7 @@ import org.apache.tools.ant.types.resources.FileResource; | |||||
| * | * | ||||
| */ | */ | ||||
| public class FileUtils { | public class FileUtils { | ||||
| private static final int DELETE_RETRY_SLEEP_MILLIS = 10; | |||||
| private static final int EXPAND_SPACE = 50; | private static final int EXPAND_SPACE = 50; | ||||
| private static final FileUtils PRIMARY_INSTANCE = new FileUtils(); | private static final FileUtils PRIMARY_INSTANCE = new FileUtils(); | ||||
| @@ -1229,7 +1230,7 @@ public class FileUtils { | |||||
| System.err.println("Rename of " + from + " to " + to + " is a no-op."); | System.err.println("Rename of " + from + " to " + to + " is a no-op."); | ||||
| return; | return; | ||||
| } | } | ||||
| if (to.exists() && !(from.equals(to.getCanonicalFile()) || to.delete())) { | |||||
| if (to.exists() && !(from.equals(to.getCanonicalFile()) || tryHardToDelete(to))) { | |||||
| throw new IOException("Failed to delete " + to + " while trying to rename " + from); | throw new IOException("Failed to delete " + to + " while trying to rename " + from); | ||||
| } | } | ||||
| File parent = to.getParentFile(); | File parent = to.getParentFile(); | ||||
| @@ -1239,7 +1240,7 @@ public class FileUtils { | |||||
| } | } | ||||
| if (!from.renameTo(to)) { | if (!from.renameTo(to)) { | ||||
| copyFile(from, to); | copyFile(from, to); | ||||
| if (!from.delete()) { | |||||
| if (!tryHardToDelete(from)) { | |||||
| throw new IOException("Failed to delete " + from + " while trying to rename it."); | throw new IOException("Failed to delete " + from + " while trying to rename it."); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1437,6 +1438,30 @@ public class FileUtils { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Accommodate Windows bug encountered in both Sun and IBM JDKs. | |||||
| * Others possible. If the delete does not work, call System.gc(), | |||||
| * wait a little and try again. | |||||
| * | |||||
| * @return whether deletion was successful | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public boolean tryHardToDelete(File f) { | |||||
| if (!f.delete()) { | |||||
| if (ON_WINDOWS) { | |||||
| System.gc(); | |||||
| } | |||||
| try { | |||||
| Thread.sleep(DELETE_RETRY_SLEEP_MILLIS); | |||||
| } catch (InterruptedException ex) { | |||||
| // Ignore Exception | |||||
| } | |||||
| return f.delete(); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /** | /** | ||||
| * Calculates the relative path between two files. | * Calculates the relative path between two files. | ||||
| * <p> | * <p> | ||||