FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
Java(TM) SE Runtime Environment (build pap6470sr5-20130619_01(SR5))
IBM J9 VM (build 2.6, JRE 1.7.0 AIX ppc64-64 Compressed References 20130617_152572 (JIT enabled, AOT enabled)
J9VM - R26_Java726_SR5_20130617_1436_B152572
JIT - r11.b04_20130528_38954ifx1
GC - R26_Java726_SR5_20130617_1436_B152572_CMPRSS
J9CL - 20130617_152572)
JCL - 20130616_01 based on Oracle 7u25-b12
ADDITIONAL OS VERSION INFORMATION :
Ubuntu 12.04.5
Mac OS X 10.9.5
AIX oslevel 6.1.0.0
A DESCRIPTION OF THE PROBLEM :
Execution of Files.copy with StandardCopyOption.REPLACE_EXISTING may unexpectedly result in FileAlreadyExistsException.
This is due to the possible interleaving of another process or another thread creating the same target file.
I think that this case should be handled internally by the copy method; alternatively the documentation of the copy method should be amended, in jdk 8u45 the javadoc entry for the copy method states:
throws FileAlreadyExistsException - if the target file exists but cannot be replaced because the REPLACE_EXISTING option is not specified (optional specific exception)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached source code
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.nio.file.FileAlreadyExistsException: target
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:88)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:243)
at sun.nio.fs.UnixCopyFile.copy(UnixCopyFile.java:581)
at sun.nio.fs.UnixFileSystemProvider.copy(UnixFileSystemProvider.java:253)
at java.nio.file.Files.copy(Files.java:1274)
at CopyTest$1.run(CopyTest.java:26)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class CopyTest {
static final int N_THREADS = 2;
static final Path source = Paths.get("source");
static final Path target = Paths.get("target");
static final AtomicBoolean running = new AtomicBoolean(true);
static final Runnable copyTask = new Runnable() {
@Override
public void run() {
try {
while (running.get()) {
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
} catch (FileAlreadyExistsException e) {
System.out.println("Received unexpected exception:");
e.printStackTrace(System.out);
} catch (IOException e) {
e.printStackTrace();
}
running.set(false);
}
};
public static void main(String[] args) throws IOException, InterruptedException {
System.out.println("-- Init source delete target ---");
Files.copy(CopyTest.class.getResourceAsStream("CopyTest.class"), source, StandardCopyOption.REPLACE_EXISTING);
Files.deleteIfExists(target);
System.out.println("-- Start copying source to target ---");
ExecutorService es = Executors.newFixedThreadPool(N_THREADS);
for (int i=0; i<N_THREADS; i++)
es.submit(copyTask);
es.shutdown();
es.awaitTermination(5, TimeUnit.SECONDS);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Handle the FileAlreadyExistsException either ignoring it or retrying.
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
Java(TM) SE Runtime Environment (build pap6470sr5-20130619_01(SR5))
IBM J9 VM (build 2.6, JRE 1.7.0 AIX ppc64-64 Compressed References 20130617_152572 (JIT enabled, AOT enabled)
J9VM - R26_Java726_SR5_20130617_1436_B152572
JIT - r11.b04_20130528_38954ifx1
GC - R26_Java726_SR5_20130617_1436_B152572_CMPRSS
J9CL - 20130617_152572)
JCL - 20130616_01 based on Oracle 7u25-b12
ADDITIONAL OS VERSION INFORMATION :
Ubuntu 12.04.5
Mac OS X 10.9.5
AIX oslevel 6.1.0.0
A DESCRIPTION OF THE PROBLEM :
Execution of Files.copy with StandardCopyOption.REPLACE_EXISTING may unexpectedly result in FileAlreadyExistsException.
This is due to the possible interleaving of another process or another thread creating the same target file.
I think that this case should be handled internally by the copy method; alternatively the documentation of the copy method should be amended, in jdk 8u45 the javadoc entry for the copy method states:
throws FileAlreadyExistsException - if the target file exists but cannot be replaced because the REPLACE_EXISTING option is not specified (optional specific exception)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached source code
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.nio.file.FileAlreadyExistsException: target
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:88)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:243)
at sun.nio.fs.UnixCopyFile.copy(UnixCopyFile.java:581)
at sun.nio.fs.UnixFileSystemProvider.copy(UnixFileSystemProvider.java:253)
at java.nio.file.Files.copy(Files.java:1274)
at CopyTest$1.run(CopyTest.java:26)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class CopyTest {
static final int N_THREADS = 2;
static final Path source = Paths.get("source");
static final Path target = Paths.get("target");
static final AtomicBoolean running = new AtomicBoolean(true);
static final Runnable copyTask = new Runnable() {
@Override
public void run() {
try {
while (running.get()) {
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
} catch (FileAlreadyExistsException e) {
System.out.println("Received unexpected exception:");
e.printStackTrace(System.out);
} catch (IOException e) {
e.printStackTrace();
}
running.set(false);
}
};
public static void main(String[] args) throws IOException, InterruptedException {
System.out.println("-- Init source delete target ---");
Files.copy(CopyTest.class.getResourceAsStream("CopyTest.class"), source, StandardCopyOption.REPLACE_EXISTING);
Files.deleteIfExists(target);
System.out.println("-- Start copying source to target ---");
ExecutorService es = Executors.newFixedThreadPool(N_THREADS);
for (int i=0; i<N_THREADS; i++)
es.submit(copyTask);
es.shutdown();
es.awaitTermination(5, TimeUnit.SECONDS);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Handle the FileAlreadyExistsException either ignoring it or retrying.
- relates to
-
JDK-8314810 (fs) java/nio/file/Files/CopyInterference.java should use TestUtil::supportsLinks
- Resolved
-
JDK-8081293 java/nio/file/Files/CopyAndMove.java failed with java.nio.file.FileAlreadyExistsException intermittently
- Closed
-
JDK-8150700 (fs) FileAlreadyExistsException with Files.move with REPLACE_EXISTING
- Closed