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 SocketImpls in nonsensical ways. The changes proposed are:
Invoking
ServerSocket::accepton aServerSocketusing a customSocketImplwill not accept a connection with a platformSocketImpl. A customSocketImplcannot reliably accept a connection with a platformSocketImplso this scenario doesn't make sense, it just wasn't disallowed in the past.Invoking
ServerSocket::acceptwhen the server socket is using a platformSocketImplwill not accept a connection with a customSocketImpl. This scenario could only work if the customSocketImplhas knowledge of JDK internals, specifically the internal representation ofjava.io.FileDescriptor, and where the customSocketImpldoesn't have its own state.- The implications of #1 and #2 are that
ServerSocket::acceptwill throw anjava.io.IOExceptionwhen attempting to mix platform and customSocketImpls.
- The implications of #1 and #2 are that
Invoking
ServerSocket::accepton aServerSocketusing a platformSocketImplwhen there is a custom client socket implementation set will now accept the connection with a platformSocketImpl. Historically, the connection would have been accepted with a customSocketImpl(scenario #2) above. The implications of this change is that code usingServerSocketcan 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.
- csr of
-
JDK-8220493 Prepare Socket/ServerSocket for alternative platform SocketImpl
-
- Resolved
-