JDK-8237774 : DatagramPacket exception conditions are not clear
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 15
  • Submitted: 2020-01-23
  • Updated: 2020-02-04
  • Resolved: 2020-02-04
Related Reports
CSR :  
Description
Summary
-------

The conditions under which `Exceptions` are thrown by the constructors of `DatagramPacket`, and by several of its set and get methods, are not documented.

Problem
-------

The `@throws` are missing from the constructors and several of the methods of the `DatagramPacket` class. 

Solution
--------

Add in which `Exceptions` are thrown by the constructors and methods, and make explicit the reasons why such conditions might occur.

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

java/net/DatagramPacket.java

        /**
         * This class represents a datagram packet.
         * <p>
         * Datagram packets are used to implement a connectionless packet
         * delivery service. Each message is routed from one machine to
         * another based solely on information contained within that packet.
         * Multiple packets sent from one machine to another might be routed
         * differently, and might arrive in any order. Packet delivery is
         * not guaranteed.
         *
     +   * <p>
     +   * Unless otherwise specified, passing a {@code null} argument causes
     +   * a {@link NullPointerException NullPointerException} to be thrown.
     +   *
     +   * <p>
     +   * Methods and constructors of {@code DatagramPacket}
     +   * accept parameters of type {@link SocketAddress}.
     +   * {@code DatagramPacket} supports {@link InetSocketAddress},
     +   * and may support additional {@code SocketAddress} sub-types.
     +   *
         * @author  Pavani Diwanji
         * @author  Benjamin Renaud
         * @since   1.0
         */


         ...


        /**
         * Constructs a {@code DatagramPacket} for receiving packets of
         * length {@code length}, specifying an offset into the buffer.
         * <p>
         * The {@code length} argument must be less than or equal to
         * {@code buf.length}.
         *
         * @param   buf     buffer for holding the incoming datagram.
         * @param   offset  the offset for the buffer
         * @param   length  the number of bytes to read.
         *
     +   * @throws  IllegalArgumentException    if the length or offset
     +   *          is negative, or if the length plus the offset is
     +   *          greater than the length of the packet's given buffer.
     +   *
         * @since   1.2
         */
        public DatagramPacket(byte buf[], int offset, int length) {


         ...


        /**
         * Constructs a {@code DatagramPacket} for receiving packets of
         * length {@code length}.
         * <p>
         * The {@code length} argument must be less than or equal to
         * {@code buf.length}.
         *
         * @param   buf     buffer for holding the incoming datagram.
         * @param   length  the number of bytes to read.
         *
     +   * @throws  IllegalArgumentException    if the length is negative
     +   *          or if the length is greater than the length of the
     +   *          packet's given buffer.
         */
        public DatagramPacket(byte buf[], int length) {


         ...


         * @param   buf     the packet data.
         * @param   offset  the packet data offset.
         * @param   length  the packet data length.
     -   * @param   address  the destination address.
     +   * @param   address the destination address, or {@code null}.
         * @param   port    the destination port number.
     +   *
     +   * @throws  IllegalArgumentException    if the length or offset
     +   *          is negative, or if the length plus the offset is
     +   *          greater than the length of the packet's given buffer,
     +   *          or if the port is out of range.
     +   *
         * @see     java.net.InetAddress
         *
         * @since   1.2
         */
        public DatagramPacket(byte buf[], int offset, int length,
                              InetAddress address, int port) {


         ...


         *
         * @param   buf     the packet data.
         * @param   offset  the packet data offset.
         * @param   length  the packet data length.
         * @param   address the destination socket address.
     -   * @throws  IllegalArgumentException if address type is not supported
     +   *
     +   * @throws  IllegalArgumentException    if address is null or its
     +   *          type is not supported, or if the length or offset is negative, 
     +   *          or if the length plus the offset is greater than the length 
     +   *          of the packet's given buffer.
     +   *
         * @see     java.net.InetAddress
         *
         * @since   1.4
         */
        public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {


         ...
    

         *
         * @param   buf     the packet data.
         * @param   length  the packet length.
     -   * @param   address  the destination address.
     +   * @param   address the destination address, or {@code null}.
         * @param   port    the destination port number.
     +   *
     +   * @throws  IllegalArgumentException    if the length is negative,
     +   *          or if the length is greater than the length of the
     +   *          packet's given buffer, or if the port is out of range.
     +   *
         * @see     java.net.InetAddress
         */
        public DatagramPacket(byte buf[], int length,
                            InetAddress address, int port) {


         ...
    
    
         * @param   buf      the packet data.
         * @param   length   the packet length.
         * @param   address  the destination address.
     -   * @throws  IllegalArgumentException if address type is not supported
     -   * @since 1.4
     +   *
     +   * @throws  IllegalArgumentException    if address is null or its
     +   *          type is not supported, or if the length is negative, or if the 
     +   *          length is greater than the length of the packet's given buffer, 
     +   *          or if the port is out of range.
     +   *
         * @see     java.net.InetAddress
     +   *
     +   * @since   1.4
         */
        public DatagramPacket(byte buf[], int length, SocketAddress address) {


         ...
    

        /**
         * Set the data buffer for this packet. This sets the
         * data, length and offset of the packet.
         *
         * @param buf the buffer to set for this packet
     -   *
         * @param offset the offset into the data
     -   *
         * @param length the length of the data
         *       and/or the length of the buffer used to receive data
         *
     -   * @throws    NullPointerException if the argument is null
     +   * @throws  IllegalArgumentException    if the length or offset
     +   *          is negative, or if the length plus the offset is
     +   *          greater than the length of the packet's given buffer.
         *
         * @see #getData
         * @see #getOffset
         * @see #getLength
         *
         * @since   1.2
         */
        public synchronized void setData(byte[] buf, int offset, int length) {


         ...
    
    
        /**
         * Sets the port number on the remote host to which this datagram
         * is being sent.
     +   *
         * @param   iport the port number
     -   * @since   1.1
     +   *
     +   * @throws  IllegalArgumentException    if the port is out of range
     +   *
         * @see     #getPort()
     +   *
     +   * @since   1.1
         */
        public synchronized void setPort(int iport) {


         ...
    
    
        /**
         * Sets the SocketAddress (usually IP address + port number) of the remote
         * host to which this datagram is being sent.
         *
         * @param   address the {@code SocketAddress}
     +   *
         * @throws  IllegalArgumentException if address is null or is a
     -   *          SocketAddress subclass not supported by this socket
     +   *          SocketAddress subclass not supported.
         *
     -   * @since 1.4
         * @see     #getSocketAddress
     +   *
     +   * @since   1.4
         */
        public synchronized void setSocketAddress(SocketAddress address) {


         ...


        /**
         * Set the length for this packet. The length of the packet is
         * the number of bytes from the packet's data buffer that will be
         * sent, or the number of bytes of the packet's data buffer that
         * will be used for receiving data. The length must be lesser or
         * equal to the offset plus the length of the packet's buffer.
         *
         * @param   length      the length to set for this packet.
         *
     +   * @throws  IllegalArgumentException    if the length is negative,
     +   *          or if the length plus the offset is greater than the
     +   *          length of the packet's data buffer.
         *
         * @see     #getLength
         * @see     #setData
         *
         * @since   1.1
         */
        public synchronized void setLength(int length) {


         ...


        /**
         * Sets the IP address of the machine to which this datagram
         * is being sent.
         *
     -   * @param   iaddr  the {@code InetAddress}.
     +   * @param   iaddr   the {@code InetAddress}, or {@code null}.
         *
         * @see     #getAddress()
         *
         * @since   1.1
         */
         public synchronized void setAddress(InetAddress iaddr) {
Comments
Moving to Approved.
04-02-2020

Thanks for the suggestion, Joe. I've updated the CSR above to include a class-level statement, and removed the @throws clauses.
31-01-2020

Was consideration given to a blanket class-level statement like "Methods and constructors in this class through NullPointerException for null buffer arguments." as opposed to an @throws clause for each method/constructor?
30-01-2020