JDK-8024710 : Setting socket timeout results in a java.net.SocketException: Invalid argument
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 7u25
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: os_x
  • Submitted: 2013-09-09
  • Updated: 2013-09-12
  • Resolved: 2013-09-12
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Darwin localhost 12.4.1 Darwin Kernel Version 12.4.1: Tue May 21 17:04:50 PDT 2013; root:xnu-2050.40.51~1/RELEASE_X86_64 x86_64

A DESCRIPTION OF THE PROBLEM :
When a java process has more than 1024 file descriptors open, any operation that results in a call to NET_Timeout in net_util_md.c will get a SocketException: Invalid argument.  That includes opening a SocketInputStream or calling accept() on a ServerSocket.

This is the issue discussed in this StackOverflow entry:

http://stackoverflow.com/questions/16191236/tomcat-startup-fails-due-to-java-net-socketexception-invalid-argument-on-mac-o

REGRESSION.  Last worked in version 6u43

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
You should see the console print "I'm here
Done".
ACTUAL -
I get an exception

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.net.SocketException: Invalid argument
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.net.SocketInputStream.read(SocketInputStream.java:203)
at org.lantern.SelectBrokenOnOSX.main(SelectBrokenOnOSX.java:59)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/**
 * <p>
 * This test demonstrates the issue seen described in <a href=
 * "http://stackoverflow.com/questions/16191236/tomcat-startup-fails-due-to-java-net-socketexception-invalid-argument-on-mac-o"
 * >this StackOverflow entry</a>.
 * </p>
 *
 * <p>
 * This test fails when running with Oracle Java 7 on OS X 10.8.4. It succeeds
 * when running on the Apple supplied Java 6 on OS X 10.8.4.
 * </p>
 */
public class SelectBrokenOnOSX {
    public static void main(String[] args) throws Exception {
        final ServerSocket serverSocket = new ServerSocket(8000);

        new Thread() {
            @Override
            public void run() {
                try {
                    Socket socket = serverSocket.accept();
                    try {
                        OutputStream out = socket.getOutputStream();
                        try {
                            out.write("I'm here".getBytes());
                        } finally {
                            out.close();
                        }
                    } finally {
                        socket.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();

        // Use 1024 file descriptors. There'll already be some in use,
        // obviously, but this guarantees the problem will occur
        for (int i = 0; i < 1024; i++) {
            new FileInputStream("/dev/null");
        }

        // This won't work unles you comment out the setSoTimeout() call
        Socket socket = new Socket("127.0.0.1", 8000);
        socket.setSoTimeout(4000);
        OutputStream out = socket.getOutputStream();
        out.write("Hello".getBytes());
        InputStream in = socket.getInputStream();
        int b;
        while ((b = in.read()) != -1) {
            System.out.print((char) b);
        }
        System.out.println("");
        out.close();
        in.close();
        socket.close();

        System.out.println("done");
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't call Socket.setSoTimeout(), or pass 0 to setSoTimeout().

This is not an acceptable workaround for any programs that aren't willing to wait indefinitely for a read/write from a socket.
Comments
Aleksej, would you mind confirming that this is a duplicate of JDK-8021820 ? If so, close it out as duplicate.
12-09-2013

Is this a duplicate of JDK-8021820 ?
12-09-2013