Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8220494

Prepare Socket/ServerSocket for alternative platform SocketImpl

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 13
    • core-libs
    • None
    • behavioral
    • medium
    • Hide
      The InputStream and OutputStream historically returned by Socket getInputStream() and getOutputStream() methods extend java.io.FileInputStream and java.io.FileOutputStream respectively. This implementation detail was never documented. The changes proposed in this CSR re-implement these two methods to return input/output streams that return a different implementation type. It is possible, but unlikely, that there is existing code that assumes the implementation type.

      Mixing of platform and custom SocketImpls in nonsensical ways is prohibited, as detailed in the Solution section.
      Show
      The InputStream and OutputStream historically returned by Socket getInputStream() and getOutputStream() methods extend java.io.FileInputStream and java.io.FileOutputStream respectively. This implementation detail was never documented. The changes proposed in this CSR re-implement these two methods to return input/output streams that return a different implementation type. It is possible, but unlikely, that there is existing code that assumes the implementation type. Mixing of platform and custom SocketImpls in nonsensical ways is prohibited, as detailed in the Solution section.
    • Java API
    • Implementation

      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:

      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 SocketImpls.
      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.

            alanb Alan Bateman
            alanb Alan Bateman
            Chris Hegarty, Michael McMahon
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: