-
CSR
-
Resolution: Approved
-
P4
-
None
-
behavioral
-
low
-
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.
-
Java API
-
SE
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() {
- csr of
-
JDK-8235783 DatagramSocket::connect and DatagramSocket::disconnect should allow an implementation to throw UncheckedIOException
-
- Resolved
-