JDK-8022126 : Remove throws SocketException from DatagramPacket constructors accepting SocketAddress
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.4.2,6,7,8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-08-02
  • Updated: 2017-05-17
  • Resolved: 2013-08-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b105Fixed
Description
Two DatagramPacket constructors declare that they throw SocketException.

     DatagramPacket(byte[] buf, int len, SocketAddress sa) throws SocketException
     DatagramPacket(byte[] buf, int off, int len, SocketAddress sa) throws SocketException

As it happens 'throws SE' was incorrectly added to these constructors when introduced in 1.4. The original API specified that SE was thrown when the given SocketAddress was not supported. That was later changed to throw IAE, in 1.4.2. These constructor now can never throw SE.

Removing 'throws SE' from the method declaration is a binary compatible change, but not source compatible ( XXX  is never thrown in body of corresponding try statement ).

see discussion on:
  http://mail.openjdk.java.net/pipermail/net-dev/2013-July/006889.html
  (cont'd) http://mail.openjdk.java.net/pipermail/net-dev/2013-August/006914.html

The conclusion of the discussion is that since these constructors are not that widely used (the InetAddress+port variants are popular) . Where they are, the affected code typically sends the packet, which requires handling of IOException anyway.

For completeness, here is a simple test that demonstrates the source incompatibility.

 : cat ThrowingCtrs.java
import java.net.*;
import java.io.IOException;

public class ThrowingCtrs {

    public static void main(String[] args) {
        SocketAddress sa = new InetSocketAddress("127.0.0.1", 45678);

        // DatagramPacket(byte[], int, SocketAddress)
        try { DatagramPacket dp = new DatagramPacket(new byte[1], 1, sa); }
        catch (SocketException x) { }

        try { DatagramPacket dp = new DatagramPacket(new byte[1], 1, sa); }
        catch (IOException x) { }

        try { DatagramPacket dp = new DatagramPacket(new byte[1], 1, sa); }
        catch (Exception x) { }

        // DatagramPacket(byte[], int, int, SocketAddress)
        try { DatagramPacket dp = new DatagramPacket(new byte[1], 0, 1, sa); }
        catch (SocketException x) { }

        try { DatagramPacket dp = new DatagramPacket(new byte[1], 0, 1, sa); }
        catch (IOException x) { }

        try { DatagramPacket dp = new DatagramPacket(new byte[1], 0, 1, sa); }
        catch (Exception x) { }
    }
}

: build/solaris-x86_64-normal-server-release/jdk/bin/javac ThrowingCtrs.java
ThrowingCtrs.java:11: error: exception SocketException is never thrown in body of corresponding try statement
        catch (SocketException x) { }
        ^
ThrowingCtrs.java:14: error: exception IOException is never thrown in body of corresponding try statement
        catch (IOException x) { }
        ^
ThrowingCtrs.java:21: error: exception SocketException is never thrown in body of corresponding try statement
        catch (SocketException x) { }
        ^
ThrowingCtrs.java:24: error: exception IOException is never thrown in body of corresponding try statement
        catch (IOException x) { }
        ^
4 errors

Comments
Suggested release note, for the Source Compatibility section: In the Java SE 8 release, the java.net.DatagramPacket constructors, that accept a java.net.SocketAddress argument, no longer declare that a java.net.SocketException can be thrown. In previous releases, java.net.SocketException was never thrown by these constructors. Compiling existing code, with Java SE 8, that explicitly catches SocketException, or its superclass java.io.IOException, may fail with "SocketException/IOException is never thrown in body of corresponding try statement". Simply remove the explicitly catch for the appropriate Exception type, as it is not needed.
20-12-2013

FWIW, this issue was uncovered as a consequence of the doclint cleanup effort.
07-08-2013