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

(spec) Socket.connect(addr,timeout) not clear if IOException because of TCP timeout

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P3 P3
    • 26
    • core-libs
    • None
    • behavioral
    • minimal
    • No risk - this is a documentation only fix
    • Java API
    • SE

      Summary

      An @apiNote is added to the javadoc of java.net.Socket.connect(SocketAddress endpoint, int timeout) to explain that a java.net.SocketTimeoutException is raised only when the given timeout expires before any other connection errors, including operating system specific connect timeout, occur.

      Problem

      The connect(SocketAddress endpoint, int timeout) method on Socket takes a timeout value which is considered to be the maximum amount of time to wait for a successful connection. This method specifies that a SocketTimeoutException is thrown if the timeout expires before connecting.

      Several factors play a role in establishing a TCP/IP connection, including connection timeout that is imposed by the operating system. If the operating system timeout occurs before the user supplied timeout to this method, then this method throws an IOException, which can resemble:

      Exception in thread "main" java.net.ConnectException: Operation timed out
          at java.base/sun.nio.ch.Net.connect0(Native Method)
          at java.base/sun.nio.ch.Net.connect(Net.java:589)
          at java.base/sun.nio.ch.Net.connect(Net.java:578)
          at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
          at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
          at java.base/java.net.Socket.connect(Socket.java:751)

      Users find it surprising that the connect operation that failed, due to the operating system timeout, throws IOException instead of SocketTimeoutException.

      The timeout parameter to the Socket.connect() method has always been an usability feature to prevent applications hanging for a long time. It was never meant to override the operating system timeout, whose value might be lower than what the users pass to this method. The current documentation of this method however doesn't provide this guidance to developers thus resulting in confusion about the semantics of this method.

      Solution

      An @apiNote is added to explain how the operating system connect timeout may play a role in what exception gets thrown from this method.

      Specification

      diff --git a/src/java.base/share/classes/java/net/Socket.java b/src/java.base/share/classes/java/net/Socket.java
      +     * @apiNote Establishing a TCP/IP connection is subject to connection timeout settings
      +     * in the operating system. The typical operating system timeout is 60 seconds. If the
      +     * operating system timeout expires before the {@code timeout} specified to this method
      +     * then an {@code IOException} is thrown. The {@code timeout} specified to this method
      +     * is typically a timeout value that is shorter than the operating system timeout.
      +     *
            * @param   endpoint the {@code SocketAddress}
            * @param   timeout  the timeout value to be used in milliseconds.
            * @throws  IOException if an error occurs during the connection, the socket
            public void connect(SocketAddress endpoint, int timeout) throws IOException {

            jpai Jaikiran Pai
            dkorbel David Korbel (Inactive)
            Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated: