-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
None
$ cat NIOTest.java
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NIOTest {
public static void main(String[] args) throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(null);
SocketAddress saddr = server.getLocalAddress();
Thread t = new Thread(() -> {
try {
SocketChannel channel = SocketChannel.open(saddr);
Socket s = channel.socket();
s.setSoTimeout(10000);
InputStream is = s.getInputStream();
byte[] buf = new byte[10];
try {
is.read(buf);
} catch (Exception e) {
// now channel is closed
is.read(buf);
}
} catch (Exception e) {
e.printStackTrace();
}
});
t.start();
Thread.sleep(1000);
t.interrupt();
}
}
$ java NIOTest(jdk 8)
java.nio.channels.IllegalBlockingModeException
at sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:202)
at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.io.InputStream.read(InputStream.java:101)
at NIOTest.lambda$main$0(NIOTest.java:24)
at java.lang.Thread.run(Thread.java:748)
$java NIOTest(jdk 11)
java.nio.channels.AsynchronousCloseException
at java.base/java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
at java.base/sun.nio.ch.SocketChannelImpl.endRead(SocketChannelImpl.java:334)
at java.base/sun.nio.ch.SocketChannelImpl.pollRead(SocketChannelImpl.java:970)
at java.base/sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:209)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.base/java.io.InputStream.read(InputStream.java:205)
at NIOTest.lambda$main$0(NIOTest.java:24)
at java.base/java.lang.Thread.run(Thread.java:834)
$java NIOTest(jdk/jdk)
java.nio.channels.ClosedChannelException
at java.base/sun.nio.ch.SocketChannelImpl.ensureOpenAndConnected(SocketChannelImpl.java:215)
at java.base/sun.nio.ch.SocketChannelImpl.blockingRead(SocketChannelImpl.java:1254)
at java.base/sun.nio.ch.SocketAdaptor$1.read(SocketAdaptor.java:191)
at java.base/java.io.InputStream.read(InputStream.java:218)
at NIOTest.lambda$main$0(NIOTest.java:24)
at java.base/java.lang.Thread.run(Thread.java:831)
BackportJDK-8246707 to 11 can solve the problem of 11, but it cannot backport to 8 because SocketChannel implementation was refactored in JDK 11
Proposed fix:
diff -r b54c25e76b6d src/share/classes/sun/nio/ch/SocketAdaptor.java
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java Fri Jan 15 17:21:26 2021 +0000
+++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java Tue Feb 02 09:13:53 2021 +0800
@@ -198,6 +198,8 @@
throws IOException
{
synchronized (sc.blockingLock()) {
+ if (!sc.isOpen())
+ throw new ClosedChannelException();
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NIOTest {
public static void main(String[] args) throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(null);
SocketAddress saddr = server.getLocalAddress();
Thread t = new Thread(() -> {
try {
SocketChannel channel = SocketChannel.open(saddr);
Socket s = channel.socket();
s.setSoTimeout(10000);
InputStream is = s.getInputStream();
byte[] buf = new byte[10];
try {
is.read(buf);
} catch (Exception e) {
// now channel is closed
is.read(buf);
}
} catch (Exception e) {
e.printStackTrace();
}
});
t.start();
Thread.sleep(1000);
t.interrupt();
}
}
$ java NIOTest(jdk 8)
java.nio.channels.IllegalBlockingModeException
at sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:202)
at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.io.InputStream.read(InputStream.java:101)
at NIOTest.lambda$main$0(NIOTest.java:24)
at java.lang.Thread.run(Thread.java:748)
$java NIOTest(jdk 11)
java.nio.channels.AsynchronousCloseException
at java.base/java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
at java.base/sun.nio.ch.SocketChannelImpl.endRead(SocketChannelImpl.java:334)
at java.base/sun.nio.ch.SocketChannelImpl.pollRead(SocketChannelImpl.java:970)
at java.base/sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:209)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.base/java.io.InputStream.read(InputStream.java:205)
at NIOTest.lambda$main$0(NIOTest.java:24)
at java.base/java.lang.Thread.run(Thread.java:834)
$java NIOTest(jdk/jdk)
java.nio.channels.ClosedChannelException
at java.base/sun.nio.ch.SocketChannelImpl.ensureOpenAndConnected(SocketChannelImpl.java:215)
at java.base/sun.nio.ch.SocketChannelImpl.blockingRead(SocketChannelImpl.java:1254)
at java.base/sun.nio.ch.SocketAdaptor$1.read(SocketAdaptor.java:191)
at java.base/java.io.InputStream.read(InputStream.java:218)
at NIOTest.lambda$main$0(NIOTest.java:24)
at java.base/java.lang.Thread.run(Thread.java:831)
Backport
Proposed fix:
diff -r b54c25e76b6d src/share/classes/sun/nio/ch/SocketAdaptor.java
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java Fri Jan 15 17:21:26 2021 +0000
+++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java Tue Feb 02 09:13:53 2021 +0800
@@ -198,6 +198,8 @@
throws IOException
{
synchronized (sc.blockingLock()) {
+ if (!sc.isOpen())
+ throw new ClosedChannelException();
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
- duplicates
-
JDK-6878250 (so) IllegalBlockingModeException thrown when reading from a closed SocketChannel's InputStream
-
- Resolved
-