Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8024710

Setting socket timeout results in a java.net.SocketException: Invalid argument

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 7u25
    • core-libs

      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.

            aefimov Aleksej Efimov
            coffeys Sean Coffey
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: