-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
1.4.0
-
x86
-
windows_2000
Name: nt126004 Date: 03/06/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
ADDITIONAL OPERATING SYSTEMS :
A DESCRIPTION OF THE PROBLEM :
NOTE: This seems to be a regression bug, since it worked
correctly in Merlin-beta3 (build 1.4.0-beta3-b84). Since
1.4RC and now in 1.4.0, it is not working.
When using a DatagramChannel is it not possible to
asynchronously interrupt or close it. Accourding to the
specifications, if interrupt() is called on the channel's
thread, a java.nio.channels.ClosedByInterruptException
should be thrown. And if the channel's close() method is
called a java.nio.channels.AsynchronousCloseException
should be called. Neither of these work.
The thread dump of the sample program exhibithing this
incorrect behaviour clearly shows that the DatagramChannel
is blocked on a receive, and the main thread is blocked
trying to kill it:
Full thread dump Java HotSpot(TM) Client VM (1.4.0-b92
mixed mode):
"Channel Thread" prio=5 tid=0x0AAFDA60 nid=0x2328 runnable
[ae8f000..ae8fdb4]
at sun.nio.ch.DatagramChannelImpl.receive0(Native
Method)
at
sun.nio.ch.DatagramChannelImpl.receiveIntoNativeBuffer
(DatagramChanne
lImpl.java:173)
at sun.nio.ch.DatagramChannelImpl.receive
(DatagramChannelImpl.java:159)
at sun.nio.ch.DatagramChannelImpl.receive
(DatagramChannelImpl.java:116)
- locked <02A06D08> (a java.lang.Object)
at Client$1.run(Client.java:37)
"Signal Dispatcher" daemon prio=10 tid=0x008E3620
nid=0x2354 waiting on monitor
[0..0]
"Finalizer" daemon prio=9 tid=0x0AA90D60 nid=0x2168 waiting
on monitor [ad4f000.
.ad4fdb4]
at java.lang.Object.wait(Native Method)
- waiting on <02A80138> (a
java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove
(ReferenceQueue.java:111)
- locked <02A80138> (a
java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove
(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run
(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x0AA90160
nid=0x2284 waiting on monitor
[ad0f000..ad0fdb4]
at java.lang.Object.wait(Native Method)
- waiting on <02A801A0> (a
java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:426)
at java.lang.ref.Reference$ReferenceHandler.run
(Reference.java:113)
- locked <02A801A0> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x00234A10 nid=0x22fc waiting for monitor
entry [6f000..6fc3c]
at sun.nio.ch.DatagramChannelImpl.kill
(DatagramChannelImpl.java:492)
- waiting to lock <02A06D08> (a java.lang.Object)
at
sun.nio.ch.DatagramChannelImpl.implCloseSelectableChannel
(DatagramCha
nnelImpl.java:487)
at
java.nio.channels.spi.AbstractSelectableChannel.implCloseCha
nnel(Abst
ractSelectableChannel.java:202)
at
java.nio.channels.spi.AbstractInterruptibleChannel$1.interru
pt(Abstra
ctInterruptibleChannel.java:147)
- locked <02A06CF0> (a java.lang.Object)
at java.lang.Thread.interrupt(Thread.java:741)
at Client.<init>(Client.java:60)
at Client.main(Client.java:71)
"VM Thread" prio=5 tid=0x0094F460 nid=0x2344 runnable
"VM Periodic Task Thread" prio=10 tid=0x008E22D0 nid=0x2340
waiting on monitor
"Suspend Checker Thread" prio=10 tid=0x008E2C60 nid=0x2360
runnable
REGRESSION. Last worked in version 1.4
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
USE JDK 1.4.0
1. Create a thread that opens a datagram channel and
receives from it
2. From another thread attempt to close the channel or
interrupt the thread
3. the threads lock: the datagram channel thread is blocked
on i/o, and the other thread is blocked on trying to kill
the channel
Using the provided code, execute Client.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
Depending on the closing method the expected results are:
java.nio.channels.AsynchronousCloseException
at java.nio.channels.spi.AbstractChannel.end
(AbstractChannel.java:184)
at sun.nio.ch.DatagramChannelImpl.receive
(DatagramChannelImpl.java:140)
at Client$1.run(Client.java:36)
-or-
java.nio.channels.ClosedByInterruptException
at java.nio.channels.spi.AbstractChannel.end
(AbstractChannel.java:183)
at sun.nio.ch.DatagramChannelImpl.receive
(DatagramChannelImpl.java:140)
at Client$1.run(Client.java:37)
Actual Results:
-no exceptions-
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//---- Client.java ---
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
public class Client
{
DatagramChannel channel;
Client()
{
try
{
channel = DatagramChannel.open();
ByteBuffer buf = ByteBuffer.allocate(1000);
buf.put("This is a datagram message".getBytes());
buf.flip();
final InetSocketAddress address = new InetSocketAddress
("225.100.10.101",8099);
// send the datagram message
channel.send(buf, address);
// create a new thread the wait for the responses
Thread t = new Thread()
{
private Charset charset = Charset.forName("US-ASCII");
private CharsetDecoder decoder = charset.newDecoder();
ByteBuffer buf2 = ByteBuffer.allocate(1000);
public void run()
{
boolean interruptedOrClosed = false;
// keep trying till this flag is set
while(!interruptedOrClosed)
{
try
{
buf2.clear();
// even if we set the socket timeout, it doesn't work
// channel.socket().setSoTimeout(2000);
System.out.println("thread waiting to recieve...");
channel.receive(buf2);
// if a server responds
System.out.println("waiting thread received something");
buf2.flip();
System.out.println(decoder.decode(buf2).toString());
}
catch(Exception e)
{
System.out.println("Some Exception");
// should be AsynchronousClose or ClosedByInterrupt
// depending on call made below
e.printStackTrace();
interruptedOrClosed = true;
}
}
}
};
// start the thread to wait for a response
t.start();
// we will sleep and on awakening try to stop the waiting thread
System.out.println("main thread sleeping for 2s");
Thread.sleep(2000);
// either use the close() or interrupt() way, comment out one or the
// other to see that both work.
//System.out.println("attempting to close channel");
//channel.close();
System.out.println("attempting to interrupt inner thread");
t.interrupt();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Main thread complete");
}
public static void main (String[] args)
{
new Client();
}
}
//--- End of Client.java ---
==============================================================================
// if you want to run the server, here is a quick server that
// should respond once
// -- Server.java --
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
public class Server
{
MulticastSocket socket;
private Charset charset = Charset.forName("US-ASCII");
private CharsetDecoder decoder = charset.newDecoder();
Server()
{
try
{
InetAddress group = InetAddress.getByName("225.100.10.101");
socket = new MulticastSocket(8099);
socket.joinGroup(group);
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
socket.receive(recv);
System.out.println("Received: " + new String(recv.getData
()).trim());
InetAddress sender = recv.getAddress();
String reply = "This is a reply";
DatagramPacket send = new DatagramPacket(reply.getBytes(),
reply.length() ,recv.getAddress(), recv.getPort());
socket.send(send);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main (String[] args)
{
new Server();
}
}
// -- End of Server.java --
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Not use latest version of 1.4, but keep using Merlin-beta3
Release Regression From : merlin-beta3
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 139763)
======================================================================
- duplicates
-
JDK-4470470 (ch) Asynchronous closing and interruption broken (win, sol)
-
- Closed
-