Summary
Add verbiage clarifying that a FileAlreadyExistsException
could be thrown for a non-atomic move despite the REPLACE_EXISTING
CopyOption
being included in the options
parameter.
Problem
If a move is not being performed atomically and the target file exists, then the target file will first be deleted and then the source file copied to the target location. If something else on the system causes a file to be created at the target location after the delete but before the copy, then a FileAlreadyExistsException
may be thrown even if the REPLACE_EXISTING
option is specified. This contravenes the current specification of when this exception is thrown.
Solution
Add verbiage clarifying the situation.
Specification
--- a/src/java.base/share/classes/java/nio/file/Files.java
+++ b/src/java.base/share/classes/java/nio/file/Files.java
@@ -1358,6 +1358,9 @@ public static Path copy(Path source, Path target, CopyOption... options)
* associated with a different provider to this object. </td>
* </tbody>
* </table>
+ * If the {@code ATOMIC_MOVE} option is not specified, then the check
+ * whether the target file exists and the actual move might not be atomic
+ * with respect to other filesystem activities.
*
* <p> An implementation of this interface may support additional
* implementation specific options.
@@ -1403,8 +1406,11 @@ public static Path copy(Path source, Path target, CopyOption... options)
* if the array contains a copy option that is not supported
* @throws FileAlreadyExistsException
* if the target file exists but cannot be replaced because the
- * {@code REPLACE_EXISTING} option is not specified <i>(optional
- * specific exception)</i>
+ * {@code REPLACE_EXISTING} option is <i>not</i> specified.
+ * It may also be thrown when the {@code REPLACE_EXISTING} option
+ * <i>is</i> specified, the move is not atomic, and the target
+ * file is created by some other entity at around the same time
+ * that this method is called
* @throws DirectoryNotEmptyException
* the {@code REPLACE_EXISTING} option is specified but the file
* cannot be replaced because it is a non-empty directory, or the
- csr of
-
JDK-8321561 (fs) Clarify non-atomic behavior of Files.move
-
- Resolved
-