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

java.net.SocketException: Invalid argument due to use of select() on Darwin

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version " 1.7.0_21 "
      Java(TM) SE Runtime Environment (build 1.7.0_21-b12)
      Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Mac OS 10.8.3

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Darwin Kernel Version 12.3.0: Sun Jan 6 22:37:10 PST 2013; root:xnu-2050.22.13~1/RELEASE_X86_64 x86_64

      A DESCRIPTION OF THE PROBLEM :
      We've had consistent problems with a Tomcat based application on Mac OS due to java.net.SocketException: Invalid argument from JNI code:

      SEVERE: StandardServer.await: accept:
      java.net.SocketException: Invalid argument
            at java.net.PlainSocketImpl.socketAccept(Native Method)
            at java.net.PlainSocketImpl.socketAccept(PlainSocketImpl.java)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
            at java.net.ServerSocket.implAccept(ServerSocket.java:522)
            at java.net.ServerSocket.accept(ServerSocket.java:490)
            at org.apache.catalina.core.StandardServer.await(StandardServer.java:431)
            at org.apache.catalina.startup.Catalina.await(Catalina.java:676)
            at org.apache.catalina.startup.Catalina.start(Catalina.java:628)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:601)
            at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
            at mycompany.tomcat.startup.ThreadDumpWrapper.main(ThreadDumpWrapper.java:260)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:601)
            at org.tanukisoftware.wrapper.WrapperStartStopApp.run(WrapperStartStopApp.java:238)
            at java.lang.Thread.run(Thread.java:722)

        Bug 7131399 changed from poll() to select() on Mac OS, however select() has an important limitation: if the application is using more than 1024 file descriptors, the select call will fail with an EINVAL.

      References:

      * http://stackoverflow.com/questions/16191236/tomcat-startup-fails-due-to-java-net-socketexception-invalid-argument-on-mac-o
      * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7131399
      * http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/_select.h?txt
      * https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/select.2.html

      REGRESSION. Last worked in version 6u45

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Attempt a socket operation that will call NET_Timeout in an application using > 1024 file descriptors

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The socket operation succeeds
      ACTUAL -
      The exception java.net.SocketException: Invalid argument is thrown

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Executable test case result:

      Exception in thread " main " java.net.SocketException: Invalid argument
      at java.net.PlainSocketImpl.socketAccept(Native Method)
      at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
      at java.net.ServerSocket.implAccept(ServerSocket.java:522)
      at java.net.ServerSocket.accept(ServerSocket.java:490)
      at SelectTest.main(SelectTest.java:13)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.*;
      import java.net.*;

      public class SelectTest {

        public static void main(String[] args) throws Exception {
          // Allocate 1024 file descriptors - some will already be in use of course
          for(int i = 0; i < 1024; i++) {
            new FileInputStream( " /dev/null " );
          }

          ServerSocket socket = new ServerSocket(8080);
          socket.accept();
        }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      select() can be used without this limit on Darwin be setting _DARWIN_UNLIMITED_SELECT:

      /*
       * This is called from sys/select.h and sys/time.h for the common prototype
       * of select(). Setting _DARWIN_C_SOURCE or _DARWIN_UNLIMITED_SELECT uses
       * the version of select() that does not place a limit on the first argument
       * (nfds). In the UNIX conformance case, values of nfds greater than
       * FD_SETSIZE will return an error of EINVAL.
       */

            aefimov Aleksej Efimov
            webbuggrp Webbug Group
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: