-
Type:
Bug
-
Resolution: Duplicate
-
Priority:
P4
-
None
-
Affects Version/s: 21.0.9, 25
-
Component/s: core-libs
-
linux
ADDITIONAL SYSTEM INFORMATION :
Linux
A DESCRIPTION OF THE PROBLEM :
A write on a ChannelOutputStream, acquired via Files.newOutputStream, will race against a concurrent stream close() and easily bypass the expected delivery of ClosedChannelException (IOException), and instead throw a RuntimeException when FileChannelImpl created for the stream is closed asynchronously from another thread.
The RuntimeException is not expected (an IOException would be preferred)
FileChannelImpl's return of 0 for !isOpen() is unlikely to match with documentation indicating the FileChannel expected behavior, either for pre-write or in-progress write experiencing a close:
```
ClosedChannelException - If this channel is closed
AsynchronousCloseException - If another thread closes this channel while the write operation is in progress
```
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the provided reproducer
---------- BEGIN SOURCE ----------
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.channels.ClosedChannelException;
class closeForWrite {
public static void main(String[] args) throws Exception {
long occursIn = triggerRuntimeException();
System.out.println(String.format("Occurs within %d close() calls", occursIn));
}
private static long triggerRuntimeException() {
long attempts = 0;
for (;;) {
try {
attempts++;
attempt();
} catch (ClosedChannelException e) {
// ignore
} catch (Exception e) {
e.printStackTrace();
return attempts;
}
}
}
private static void attempt() throws Exception {
OutputStream out = Files.newOutputStream(Paths.get("testing"));
Thread thread = new Thread(() -> {
try {
Thread.sleep(10);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
try {
int b = 0;
for (;;) {
out.write(b);
}
} finally {
thread.join();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
serializing writes with closes by stream would probably prevent this.
FREQUENCY :
OFTEN
Linux
A DESCRIPTION OF THE PROBLEM :
A write on a ChannelOutputStream, acquired via Files.newOutputStream, will race against a concurrent stream close() and easily bypass the expected delivery of ClosedChannelException (IOException), and instead throw a RuntimeException when FileChannelImpl created for the stream is closed asynchronously from another thread.
The RuntimeException is not expected (an IOException would be preferred)
FileChannelImpl's return of 0 for !isOpen() is unlikely to match with documentation indicating the FileChannel expected behavior, either for pre-write or in-progress write experiencing a close:
```
ClosedChannelException - If this channel is closed
AsynchronousCloseException - If another thread closes this channel while the write operation is in progress
```
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the provided reproducer
---------- BEGIN SOURCE ----------
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.channels.ClosedChannelException;
class closeForWrite {
public static void main(String[] args) throws Exception {
long occursIn = triggerRuntimeException();
System.out.println(String.format("Occurs within %d close() calls", occursIn));
}
private static long triggerRuntimeException() {
long attempts = 0;
for (;;) {
try {
attempts++;
attempt();
} catch (ClosedChannelException e) {
// ignore
} catch (Exception e) {
e.printStackTrace();
return attempts;
}
}
}
private static void attempt() throws Exception {
OutputStream out = Files.newOutputStream(Paths.get("testing"));
Thread thread = new Thread(() -> {
try {
Thread.sleep(10);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
try {
int b = 0;
for (;;) {
out.write(b);
}
} finally {
thread.join();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
serializing writes with closes by stream would probably prevent this.
FREQUENCY :
OFTEN
- duplicates
-
JDK-8361495 (fc) Async close of streams connected to uninterruptible FileChannel doesn't throw AsynchronousCloseException in all cases
-
- Resolved
-