JDK-6347873 : (so) Ports opened with ServerSocketChannel blocks when using Runtime.exec
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    windows_2000,windows_2003,windows_xp windows_2000,windows_2003,windows_xp
  • CPU: x86
  • Submitted: 2005-11-09
  • Updated: 2011-02-16
  • Resolved: 2007-04-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6 JDK 7
5.0u12Fixed 6u2Fixed 7 b12Fixed
Related Reports
Relates :  
Description
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:

Comments
SUGGESTED FIX ------- Net.c ------- *** /tmp/sccs.glaG.W Thu Oct 5 14:47:01 2006 --- Net.c Thu Oct 5 14:46:47 2006 *************** *** 43,56 **** Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean stream, jboolean reuse) { ! int fd; ! fd = (int)socket(AF_INET, (stream ? SOCK_STREAM : SOCK_DGRAM), 0); ! if (fd < 0) { ! NET_ThrowNew(env, WSAGetLastError(), "socket"); } ! ! return fd; } JNIEXPORT void JNICALL --- 43,57 ---- Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean stream, jboolean reuse) { ! SOCKET s; ! s = socket(AF_INET, (stream ? SOCK_STREAM : SOCK_DGRAM), 0); ! if (s == INVALID_SOCKET) { ! NET_ThrowNew(env, WSAGetLastError(), "socket"); ! } else { ! SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, FALSE); } ! return (jint)s; } JNIEXPORT void JNICALL
05-10-2006

EVALUATION We are missing a call to SetHandleInformation to change the socket attribute so that the socket is not inherited.
09-11-2005