FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Network: Realtek RTL8139/810x Family Fast Ethernet NIC
System: Fujitsu Siemens Amilo M 1420 (laptop), Intel Centrino with 1500 mhz
A DESCRIPTION OF THE PROBLEM :
I open a port with a ServerSocketChannel and connects with this. If I open a
process with Runtime.exec before the connection is closed, the port persists
until the process opened with Runtime.exec is killed.
I also once tried to stop the java application which opened the
ServerSocketChannel, but the port persisted. It did not close until I closed
the application/process which was started with Runtime.exec.
I have tested this with ServerSocket and Socket without any problems. Seems like
this is a problem with Channels.
I have tried to launch different applications with Runtime.exec. Internet
explorer and java applications seems to block the ports. Windows explorer did
not cause any problem.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. I open a port with ServerSocketChannel.
2. I connect to this port with a SocketChannel
3. I launch an application with Runtime.exec (in the same process/JVM which
opened ServerSocketChannel)
4. I close the connection with SocketChannel
5. ServerSocketChannel detects this and closes its connection too.
6. I repeat step 1.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A connection between the SocketChannel from ServerSocketChannel the "other"
socket channel is established, broken and the port is reopend.
ACTUAL -
I get a java.net.BindException: Address already in use: bind when performing
step 6.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.net.BindException: Address already in use: bind
at sun.nio.ch.Net.bind(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:108)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:52)
at test.TestRuntimeExec.main(TestRuntimeExec.java:34)
Exception in thread "main"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
The main class, which should be started
classes/test/TestRuntimeExec.java:
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class TestRuntimeExec {
public static void main(String[] args) throws IOException,
InterruptedException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(3456));
Thread.sleep(1000);
SocketChannel client = SocketChannel.open();
client.connect(new InetSocketAddress("localhost", 3456));
Runtime.getRuntime().exec(new String[] {
"javaw", "-cp", "classes", "test.Dummy"
});
System.out.println("exec");
Thread.sleep(1000);
client.socket().close();
client.close();
Thread.sleep(1000);
serverSocketChannel.socket().close();
serverSocketChannel.close();
Thread.sleep(1000);
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(3456));
Thread.sleep(1000);
System.out.println("end");
while (true) {
Thread.sleep(1000);
}
}
}
A dummy class, used in the Runtime.exec statement of TestRuntimeExec.java
classes/test/Dummy.java:
package test;
public class Dummy {
public static void main(String[] args) {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use SocketServer and Socket instead of SocketServerChannel and SocketChannel.
workaround: