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)