JDK-8274633 : Drop support for pre JDK 1.4 DatagramSocketImpl implementations
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 18
  • Submitted: 2021-10-01
  • Updated: 2021-11-05
  • Resolved: 2021-10-27
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Drop support for `java.net.DatagramSocketImpl` implementations written prior to Java 1.4, specifically ones which do not have support for connected sockets, for peeking at received datagrams, and for joining and leaving a group at a specific interface.  This support is legacy. Such implementations do not compile with JDK 1.4 or newer, so it should be relatively safe to drop this support. 

Problem
-------

We wish to resolve technical debt associated with `java.net.DatagramSocket/MulticastSocket`. For example, code that attempts to allow a connection to be made in a limited fashion with an old `DatagramSocketImpl` implementation, which does not implement the corresponding  `connect` method that was later added to the `DatagramSocketImpl` interface.


Solution
--------
The proposed solution is to remove the check for old impls.
In addition, we are changing the default behavior of two concrete methods in `DatagramSocketImpl`: `connect` and `disconnect`. The default implementation of these methods was to do nothing, on the assumption that a missing implementation would be detected by the check for old impl.
Now that this check is gone - we are changing the default implementation to throw an exception (a `SocketException` for `connect`, and a `UncheckIOException` for `disconnect`). 
Additional documentation for the exception clauses, and a corresponding `@implSpec`, will also be added to the javadoc for the `connect` and `disconnect` methods in `DatagramSocketImpl` where missing. This will inform users that they must provide their own implementations of these methods if they choose to provide their own `DatagramSocketImpl` implementation (see specification below).
Note: `DatagramSocket` already specifies that `SocketException` (or `UncheckedIOException`) will be thrown if `connect` (or `disconnect`) fail to connect (or disconnect) - so no changes are needed in the `DatagramSocket` API specification.

Specification
-------------

This is binary incompatible insofar as a `DatagramSocketImpl` compiled with Java 1.3, or earlier would function in some limited way with later releases, but now will not function at all. This is a behavior change. The specification for the corresponding method will be updated will an `@implSpec` note to inform the user that they must provide their own implementations of these methods if they choose to provide their own `DatagramSocketImpl` implementation (see below).

java/net/DatagramSocketImpl.java


        /**
         * Connects a datagram socket to a remote destination. This associates the remote
         * address with the local socket so that datagrams may only be sent to this destination
         * and received from this destination. This may be overridden to call a native
         * system connect.
         *
         * <p>If the remote destination to which the socket is connected does not
         * exist, or is otherwise unreachable, and if an ICMP destination unreachable
         * packet has been received for that address, then a subsequent call to
         * send or receive may throw a PortUnreachableException.
         * Note, there is no guarantee that the exception will be thrown.
         *
    +    * @implSpec The default implementation of this method throws {@code SocketException}.
         *
         * @param   address the remote InetAddress to connect to
         * @param   port the remote port number
         * @throws  SocketException may be thrown if the socket cannot be
         *          connected to the remote destination
         * @since   1.4
         */
        protected void connect(InetAddress address, int port) throws SocketException {


        /**
         * Disconnects a datagram socket from its remote destination.
         *
    +    * @implSpec The default implementation of this method throws {@code UncheckedIOException}.
         *
    +    * @throws UncheckedIOException if disconnect fails or no implementation is provided
         * @since 1.4
         */
        protected void disconnect() {


Comments
Moving amended request to Approved.
27-10-2021

The compatibility risk here is definitely low. The only 3rd party DatagramSocketImpl that we've found is in the Coherence CE github project. From what I can tell, the Coherence implementation of DatagramSocketImpl is over TCP with no support for connected datagrams and no support for joining multicast groups (it overrides join/joinGroup to throw UOE).
27-10-2021

Change in behavior (if an old impl compiled on 1.3 or earlier is used): - connect (and disconnect) will throw a `SocketException` (or `UncheckedIOException`) when called (whereas previously the behaviour of connect / disconnect would have been emulated) - joinGroup (and leaveGroup) will throw `AbstractMethodError` whereas previously `UnsupportedOperationException` would have been thrown. There should be no change for implementations compiled with 1.4 (or later) since these should implement all methods. A 1.4 implementation that wouldn't override `connect` and `disconnect` would also start throwing an exception instead of doing nothing, but it's unlikely that such implementations exist since for those the connect emulation would not have been used anyway. Throwing an exception in this case is a much better behavior.
26-10-2021

For the purposes of the CSR, the joinGroup & leaveGroup differences should be noted in the compatibility risk discussion.
26-10-2021

Moving to Provisional, not Approved. The PR mentions some possible behavioral compatibility changes related to oldImpl's. Does the current CSR fully reflect the scope of behavioral changes here?
26-10-2021