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> | ||||