JDK-8225431 : ServerSocket.implAccept should include warnings about Socket type/state
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2019-06-06
  • Updated: 2019-06-07
  • Resolved: 2019-06-07
Related Reports
CSR :  
Description
Summary
-------

The CSR for JDK-8220494 notes that a future CSR will address the minor
spec and documentation clarifications concerning behavioral changes that
prohibit mixing of platform and custom `SocketImpl`s. This CSR addresses
the specific case of accepting new connections with `ServerSocket`.
This CSR follows JDK-8220494.

Problem
-------

The `accept`, and the protected `implAccept`, methods prohibit a number
of scenarios where it is not possible to accept a new connection, i.e.
when mixing platform and custom `SocketImpl`s.

Solution
--------

This CSR proposes to 1) update the specification to clarify the expected
behavior of `accept` ( and the protected `implAccept` ) for these
mismatch scenarios, i.e. to throw an `IOException`, and 2) add an
implNote describing the behavior of the system-default SocketImpl.

Additionally, prior to the `implAccept` invocation the given Socket
may be connected, closed, or even have socket options set. A note is
added to warning against this and make it explicitly unspecified, as the
behavior cannot be guaranteed.


Specification
-------------

src/java.base/share/classes/java/net/ServerSocket.java

      /**
       * Listens for a connection to be made to this socket and accepts
       * it. The method blocks until a connection is made.
       *
       * <p>A new Socket {@code s} is created and, if there
       * is a security manager,
       * the security manager's {@code checkAccept} method is called
       * with {@code s.getInetAddress().getHostAddress()} and
       * {@code s.getPort()}
       * as its arguments to ensure the operation is allowed.
       * This could result in a SecurityException.
       *
    +  * @implNote
    +  * An instance of this class using a system-default {@code SocketImpl}
    +  * accepts sockets with a {@code SocketImpl} of the same type, regardless
    +  * of the {@linkplain Socket#setSocketImplFactory(SocketImplFactory)
    +  * client socket implementation factory}, if one has been set.
    +  *
       * @exception  IOException  if an I/O error occurs when waiting for a
       *               connection.
       * @exception  SecurityException  if a security manager exists and its
       *             {@code checkAccept} method doesn't allow the operation.
       * @exception  SocketTimeoutException if a timeout was previously set with setSoTimeout and
       *             the timeout has been reached.
       * @exception  java.nio.channels.IllegalBlockingModeException
       *             if this socket has an associated channel, the channel is in
       *             non-blocking mode, and there is no connection ready to be
       *             accepted
       *
       * @return the new Socket
       * @see SecurityManager#checkAccept
       * @revised 1.4
       * @spec JSR-51
       */
      public Socket accept() throws IOException

         /**
       * Subclasses of ServerSocket use this method to override accept()
       * to return their own subclass of socket.  So a FooServerSocket
    -  * will typically hand this method an <i>empty</i> FooSocket.  On
    -  * return from implAccept the FooSocket will be connected to a client.
    +  * will typically hand this method a newly created, unbound, FooSocket.
    +  * On return from implAccept the FooSocket will be connected to a client.
    +  *
    +  * <p> The behavior of this method is unspecified when invoked with a
    +  * socket that is not newly created and unbound. Any socket options set
    +  * on the given socket prior to invoking this method may or may not be
    +  * preserved when the connection is accepted. It may not be possible to
    +  * accept a connection when this socket has a {@code SocketImpl} of one
    +  * type and the given socket has a {@code SocketImpl} of a completely
    +  * different type.
    +  *
    +  * @implNote
    +  * An instance of this class using a system-default {@code SocketImpl}
    +  * can accept a connection with a Socket using a {@code SocketImpl} of
    +  * the same type: {@code IOException} is thrown if the Socket is using
    +  * a custom {@code SocketImpl}. An instance of this class using a
    +  * custom {@code SocketImpl} cannot accept a connection with a Socket
    +  * using a system-default {@code SocketImpl}.
       *
       * @param s the Socket
       * @throws java.nio.channels.IllegalBlockingModeException
       *         if this socket has an associated channel,
       *         and the channel is in non-blocking mode
       * @throws IOException if an I/O error occurs when waiting
    -  * for a connection.
    +  *         for a connection, or if it is not possible for this socket
    +  *         to accept a connection with the given socket
    +  *
       * @since   1.1
       * @revised 1.4
       * @spec JSR-51
       */
      protected final void implAccept(Socket s)

Comments
Moving to Approved.
07-06-2019