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

DatagramSocket::connect and DatagramSocket::disconnect should allow an implementation to throw UncheckedIOException

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 15
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      low
    • Compatibility Risk Description:
      Undocumented throwing of Errors is changed to throw a more user friendly UncheckedIOException, which this fix now makes part of the specification. It's unlikely that existing code would depend on the throwing of non-documented Errors.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      DatagramSocket's connect and disconnect methods do not throw an IOException while DatagramChannel's corresponding methods do. The potential failure behaviour of the DatagramSocket's methods should be clarified.

      Problem

      The behaviour of DatagramSocket connect and disconnect methods when an IO error occurs is not clear. For instance, the two-args DatagramSocket::connect method currently might throw an Error, which is undocumented behavior and not user-friendly.

      Solution

      Update the specification of DatagramSocket::connect and DatagramSocket::disconnect to document that an implementation may throw UncheckedIOException. In addition, and similar to what was done for DatagramChannel, an @apiNote will be added to DatagramSocket::disconnect to recommend closing the socket if an IO exception occurs, as the underlying socket might have been left in an inconsistent and unspecified state. The two-args DatagramSocket::connect implementation used to throw an Error if a SocketException occurred (for instance, if the socket was not bound and the implicit bind failed). This is undocumented behavior, and this will now be changed to throw the documented UncheckedIOException instead. Similarly the DatagramChannel socket adapter used to throw an Error if connect (two-args) or disconnect failed, and will now be changed to throw UncheckedIOException instead, in conformance to the updated specification.

      As it appears that the current omission of throws IOException from the declaration of these methods was likely an oversight - one that cannot be easily fixed now since it would be source incompatible - an UncheckedIOException is now being thrown.

      Specification

      DatagramSocket::connect

      /**
           * Connects the socket to a remote address for this socket. When a
           * socket is connected to a remote address, packets may only be
           * sent to or received from that address. By default a datagram
      -    * socket is not connected.
      +    * socket is not connected. If the socket is already closed,
      +    * then this method has no effect.
           *
      -    * <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.
      +    * <p> If this socket is not bound then this method will first cause the
      +    * socket to be bound to an address that is assigned automatically,
      +    * as if invoking the {@link #bind bind} method with a parameter of
      +    * {@code null}. 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.
           *
           * ...
           *
           * @param address the remote address for the socket
           *
           * @param port the remote port for the socket.
           *
           * @throws IllegalArgumentException
           *         if the address is null, or the port is out of range.
           *
           * @throws SecurityException
           *         if a security manager has been installed and it does
           *         not permit access to the given remote address
           *
      +    * @throws UncheckedIOException
      +    *         may be thrown if connect fails, for example, if the
      +    *         destination address is non-routable
           *
           * @see #disconnect
      +    * @since 1.2
           */
          public void connect(InetAddress address, int port) {
      
      
            * Connects this socket to a remote socket address (IP address + port number).
            *
            * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
      -     * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
      -     * with the given socket addresses IP address and port number.
      +     * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
      +     * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)},
      +     * except that {@code SocketException} that may be raised are not wrapped in
      +     * {@code UncheckedIOException}.   
      ...
      public void connect(SocketAddress addr) throws SocketException {

      DatagramSocket::disconnect

           /**
            * Disconnects the socket. If the socket is closed or not connected,
            * then this method has no effect.
            *
      +     * @apiNote If this method throws an UncheckedIOException, the socket
      +     *          may be left in an unspecified state. It is strongly
      +     *          recommended that the socket be closed when disconnect
      +     *          fails.
      +     *
      +     * @throws  UncheckedIOException
      +     *          may be thrown if it fails to dissolve the
      +     *          association and restore the socket to a consistent state
      +     *
            * @see #connect
      +     * @since 1.2
            */
           public void disconnect() {

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              pconcannon Patrick Concannon (Inactive)
              Reporter:
              dfuchs Daniel Fuchs
              Reviewed By:
              Chris Hegarty, Daniel Fuchs
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: