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:
Invoking
ServerSocket::accept
on aServerSocket
using a customSocketImpl
will not accept a connection with a platformSocketImpl
. A customSocketImpl
cannot reliably accept a connection with a platformSocketImpl
so this scenario doesn't make sense, it just wasn't disallowed in the past.Invoking
ServerSocket::accept
when the server socket is using a platformSocketImpl
will not accept a connection with a customSocketImpl
. This scenario could only work if the customSocketImpl
has knowledge of JDK internals, specifically the internal representation ofjava.io.FileDescriptor
, and where the customSocketImpl
doesn't have its own state.- The implications of #1 and #2 are that
ServerSocket::accept
will throw anjava.io.IOException
when attempting to mix platform and customSocketImpl
s.
- The implications of #1 and #2 are that
Invoking
ServerSocket::accept
on aServerSocket
using a platformSocketImpl
when 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 usingServerSocket
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.
- csr of
-
JDK-8220493 Prepare Socket/ServerSocket for alternative platform SocketImpl
-
- Resolved
-