Summary
-------
An upcoming JEP will propose to replace the underlying implementation used by `java.net.Socket` and `java.net.ServerSocket`. The new implementation has been developed to be easy to adapt to user-mode threads, a.k.a. Fibers. In preparation for this overhaul, several changes to `java.net.Socket`, `ServerSocket` and the existing underlying implementation are needed. This CSR concerns the behavioral changes of the preparatory work.
Problem
-------
`java.net.Socket` and `java.net.ServerSocket` employ a legacy, JDK 1.0 era, service provider facility. A `Socket` or `ServerSocket` delegates socket operations to a `java.net.SocketImpl`.
There are two ways to use the `SocketImpl` mechanism. One is to extend `Socket` and `ServerSocket` and call their protected constructors to create a `Socket` or `ServerSocket` with a custom `SocketImpl`. The other is to use the static methods, `Socket.setSocketFactoryImpl` and `ServerSocket.setSocketFactory`, to set the system-wide `SocketImpl` for client and server sockets.
Extending Socket to create a client/connecting `Socket` with a custom `SocketImpl` is a reasonable usage of this mechanism. It is also reasonable to create a `ServerSocket` with a custom `SocketImpl` and have it accept connections that yield `Socket` objects using the same type of custom `SocketImpl`. At a stretch, it is also not wrong to use the static methods to set the both socket implementation factories to use a custom `SocketImpl`.
The problem with this mechanism is that it can used to create scenarios where a `ServerSocket` using one type of `SocketImpl` can accept a connection with a `Socket` that is using a different type of `SocketImpl`. These scenarios can arise in unexpected ways, e.g. creating a `ServerSocket` with a custom `SocketImpl` and calling its `accept()` method creates the scenario where a custom `SocketImpl` is attempting to accept a connection with the JDK's built-in/platform `SocketImpl`. Using the static methods to set one, but not both, system wide socket implementation factories, is another example that leads to several nonsensical scenarios.
Solution
--------
A future CSR will propose deprecating both `Socket.setSocketFactoryImpl` and `ServerSocket.setSocketFactory`. In the mean-time, this CSR proposes behavioral changes that prohibit mixing of platform and custom `SocketImpl`s in nonsensical ways. The changes proposed are:
1. Invoking `ServerSocket::accept` on a `ServerSocket` using a custom `SocketImpl` will not accept a connection with a platform `SocketImpl`. A custom `SocketImpl` cannot reliably accept a connection with a platform `SocketImpl` so this scenario doesn't make sense, it just wasn't disallowed in the past.
2. Invoking `ServerSocket::accept` when the server socket is using a platform `SocketImpl` will not accept a connection with a custom `SocketImpl`. This scenario could only work if the custom `SocketImpl` has knowledge of JDK internals, specifically the internal representation of `java.io.FileDescriptor`, and where the custom `SocketImpl` doesn't have its own state.
* The implications of #1 and #2 are that `ServerSocket::accept` will throw an `java.io.IOException` when attempting to mix platform and custom `SocketImpl`s.
3. Invoking `ServerSocket::accept` on a `ServerSocket` using a platform `SocketImpl` when there is a custom client socket implementation set will now accept the connection with a platform `SocketImpl`. Historically, the connection would have been accepted with a custom `SocketImpl` (scenario #2) above. The implications of this change is that code using `ServerSocket` can co-exist in the same VM as code using a system-wide client socket implementation. Such code could not co-exist reliably in the past.
There are no observable changes to "sane" usages of the `SocketImpl` mechanism.
This CSR does not propose to introduce any system property or other means to mitigate the changes proposed here.
Specification
-------------
There are no specification changes.
An extensive release note is planned for JDK 13 to cover this and other upcoming changes to the `SocketImpl` mechanism.