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

Clarify API documentation of NetworkInterface with respect to configuration changes

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 24
    • core-libs
    • None
    • binary
    • minimal
    • The API specification is clarified, there is no change in the implementation
    • Java API
    • SE

      Summary

      NetworkInterface API documentation is enhanced to make it clear that network configuration may change at any time, and that a new Network Interface may need to be obtained to observe those changes. It also makes it clear that two instances of Network Interface representing the same underlying interface may not compare equals, and may show different set of addresses, if they were obtained by different calls to the API (and thus at different times).

      Problem

      NetworkInterface API was designed a long time ago in a time when virtual interfaces were not as common and dynamic network reconfiguration didn't happen as frequently. As such the API documentation is somewhat nebulous, and developers may infer behaviour that is inaccurate.

      Solution

      NetworkInterface should state clearly that part of the information it contains reflects a network configuration at the time the instance was created, and that a new instance should be obtained to get an up-to-date view of the configuration. It should also make it clear that two instances obtained at different time may thus reflect a different view of the configuration.

      Specification

      Clarifies Class Level API documentation:

      --- a/src/java.base/share/classes/java/net/NetworkInterface.java
      +++ b/src/java.base/share/classes/java/net/NetworkInterface.java
       /**
      - * This class represents a Network Interface made up of a name,
      - * and a list of IP addresses assigned to this interface.
      - * It is used to identify the local interface on which a multicast group
      - * is joined.
      - *
      - * Interfaces are normally known by names such as "le0".
      + * This class represents a Network Interface.
      + * <p>
      + * A Network Interface is an abstraction encapsulating
      + * the characteristics of a Network Interface Controller, or
      + * Virtual Network adapter, which is a system hardware/software
      + * component connecting a computer, or host system, to a computer
      + * network. A Network Interface can be physical or virtual.
      + * A Network Interface has a name, zero or more assigned
      + * {@linkplain InetAddress IP addresses}, zero or more {@linkplain
      + * InterfaceAddress MAC Addresses}, and may have an index.
      + * The name is highly platform specific but a name such as "le0"
      + * is typical; it may not be unique. The index is a highly platform
      + * specific number that identifies the interface. The network
      + * configuration may change during the lifetime of the JVM.
      + * For example, the set of IP addresses assigned to a network
      + * interface can be transient and dynamically allocated, and may
      + * change at any time.
      + * <p>
      + * When obtaining a {@code NetworkInterface} instance, part of its
      + * configuration (such as its name and the list of assigned IP addresses),
      + * is reflective of its configuration at creation time.
      + * Obtaining an updated view of the network configuration may require
      + * looking up a network interface again in order to obtain a new instance.
      + * <p>
      + * Network interface instances are typically used to identify the local
      + * interface on which a multicast group is joined.
      + *
      + * @apiNote <a id="lookup"></a>Several static methods in this class are
      + * factory methods, returning a new instance of a {@code NetworkInterface},
      + * reflecting the configuration at the time of instantiation.
      + * The network configuration may change at any time, and as such,
      + * these methods may need to be invoked again in order to obtain
      + * a more up-to-date view of the network interfaces.
      + * In particular, there is no guarantee that the same interface will be
      + * found at the same index, or that the same network addresses will be
      + * bound to the interface, if the network configuration of the system
      + * has changed.
       *
        * @since 1.4
        */

      Method public Enumeration getInetAddresses() gets an @implNote:

           /**
      -     * Get an Enumeration with all or a subset of the InetAddresses bound to
      +     * Get an Enumeration with all, or a subset, of the InetAddresses bound to
            * this network interface.
            * <p>
            * If there is a security manager, its {@code checkConnect}
            * method is called for each InetAddress. Only InetAddresses where
            * the {@code checkConnect} doesn't throw a SecurityException
            * will be returned in the Enumeration. However, if the caller has the
            * {@link NetPermission}("getNetworkInformation") permission, then all
            * InetAddresses are returned.
            *
      -     * @return an Enumeration object with all or a subset of the InetAddresses
      +     * @implNote
      +     * The returned enumeration contains all, or a subset, of the InetAddresses that were
      +     * bound to the interface at the time the {@linkplain #getNetworkInterfaces()
      +     * interface configuration was read}
      +     *
      +     * @return an Enumeration object with all, or a subset, of the InetAddresses
            * bound to this network interface
            * @see #inetAddresses()
            */
           public Enumeration<InetAddress> getInetAddresses() {

      Method public Stream inetAddresses() gets an @implNote:

            /**
      -     * Get a Stream of all or a subset of the InetAddresses bound to this
      +     * Get a Stream of all, or a subset, of the InetAddresses bound to this
            * network interface.
            * <p>
            * If there is a security manager, its {@code checkConnect}
            * method is called for each InetAddress. Only InetAddresses where
            * the {@code checkConnect} doesn't throw a SecurityException will be
            * returned in the Stream. However, if the caller has the
            * {@link NetPermission}("getNetworkInformation") permission, then all
            * InetAddresses are returned.
            *
      -     * @return a Stream object with all or a subset of the InetAddresses
      +     * @implNote
      +     * The stream contains all, or a subset, of the InetAddresses that were
      +     * bound to the interface at the time the {@linkplain #getNetworkInterfaces()
      +     * interface configuration was read}
      +     *
      +     * @return a Stream object with all, or a subset, of the InetAddresses
            * bound to this network interface
            * @since 9
            */
           public Stream<InetAddress> inetAddresses() {

      Method public static NetworkInterface getByName(String name) gets an @apiNote

           /**
            * Searches for the network interface with the specified name.
            *
      +     * @apiNote
      +     * The returned interface instance may reflect a snapshot of the
      +     * configuration taken at the time the instance is created.
      +     * See the general discussion of {@linkplain NetworkInterface##lookup
      +     * snapshots and configuration} for the semantics of the returned interface.
      +     *
            * @param   name
            *          The name of the network interface.
            *
            * @return  A {@code NetworkInterface} with the specified name,
            *          or {@code null} if there is no network interface
            *          with the specified name.
            *
            * @throws  SocketException
            *          If an I/O error occurs.
            *
            * @throws  NullPointerException
            *          If the specified name is {@code null}.
            */
           public static NetworkInterface getByName(String name) throws SocketException {

      Method public static NetworkInterface getByIndex(int index) gets an @apiNote:

           /**
            * Get a network interface given its index.
            *
      +     * @apiNote
      +     * The returned interface instance may reflect a snapshot of the
      +     * configuration taken at the time the instance is created.
      +     * See the general discussion of {@linkplain NetworkInterface##lookup
      +     * snapshots and configuration} for the semantics of the returned interface.
      +     *
            * @param index an integer, the index of the interface
            * @return the NetworkInterface obtained from its index, or {@code null} if
            *         there is no interface with such an index on the system
            * @throws  SocketException  if an I/O error occurs.
            * @throws  IllegalArgumentException if index has a negative value
            * @see #getIndex()
            * @since 1.7
            */
           public static NetworkInterface getByIndex(int index) throws SocketException {

      Method public static NetworkInterface getByInetAddress(InetAddress addr) gets an @apiNote:

           /**
            * Convenience method to search for a network interface that
            * has the specified Internet Protocol (IP) address bound to
            * it.
            * <p>
            * If the specified IP address is bound to multiple network
            * interfaces it is not defined which network interface is
            * returned.
            *
      +     * @apiNote
      +     * The returned interface instance may reflect a snapshot of the
      +     * configuration taken at the time the instance is created.
      +     * See the general discussion of {@linkplain NetworkInterface##lookup
      +     * snapshots and configuration} for the semantics of the returned interface.
      +     *
            * @param   addr
            *          The {@code InetAddress} to search with.
            *
            * @return  A {@code NetworkInterface}
            *          or {@code null} if there is no network interface
            *          with the specified IP address.
            *
            * @throws  SocketException
            *          If an I/O error occurs.
            *
            * @throws  NullPointerException
            *          If the specified address is {@code null}.
            */
           public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {

      @apiNote in method public static Enumeration getNetworkInterfaces() is extended:

          /**
           * Returns an {@code Enumeration} of all the interfaces on this machine. The
            * {@code Enumeration} contains at least one element, possibly representing
            * a loopback interface that only supports communication between entities on
            * this machine.
            *
      -     * @apiNote this method can be used in combination with
      -     * {@link #getInetAddresses()} to obtain all IP addresses for this node
      +     * @apiNote
      +     * This method can be used in combination with
      +     * {@link #getInetAddresses()} to obtain all IP addresses for this node.
      +     * <p>
      +     * The returned interface instances may reflect a snapshot of the
      +     * configuration taken at the time the instance is created.
      +     * See the general discussion of {@linkplain NetworkInterface##lookup
      +     * snapshots and configuration} for the semantics of the returned interface.
            *
            * @return an Enumeration of NetworkInterfaces found on this machine
            * @throws     SocketException  if an I/O error occurs,
            *             or if the platform does not have at least one configured
            *             network interface.
            * @see #networkInterfaces()
            */
           public static Enumeration<NetworkInterface> getNetworkInterfaces()

      @apiNote in method public static Stream networkInterfaces() is extended:

           /**
            * Returns a {@code Stream} of all the interfaces on this machine.  The
            * {@code Stream} contains at least one interface, possibly representing a
            * loopback interface that only supports communication between entities on
            * this machine.
            *
      -     * @apiNote this method can be used in combination with
      +     * @apiNote This method can be used in combination with
            * {@link #inetAddresses()}} to obtain a stream of all IP addresses for
            * this node, for example:
            * <pre> {@code
            * Stream<InetAddress> addrs = NetworkInterface.networkInterfaces()
            *     .flatMap(NetworkInterface::inetAddresses);
            * }</pre>
      +     * <p>
      +     * The returned interface instances may reflect a snapshot of the
      +     * configuration taken at the time the instance is created.
      +     * See the general discussion of {@linkplain NetworkInterface##lookup
      +     * snapshots and configuration} for the semantics of the returned interface.
            *
            * @return a Stream of NetworkInterfaces found on this machine
            * @throws     SocketException  if an I/O error occurs,
            *             or if the platform does not have at least one configured
            *             network interface.
            * @since 9
            */
           public static Stream<NetworkInterface> networkInterfaces()

            dfuchs Daniel Fuchs
            dfuchs Daniel Fuchs
            Alan Bateman
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: