JDK-8143923 : java.net socket supportedOptions set depends on call order
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-11-24
  • Updated: 2016-05-26
  • Resolved: 2016-05-24
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 9
9 b120Fixed
Related Reports
Relates :  
Relates :  
Description
DatagramSocket and MulticastSocket have different supported options. But option set is cached depends on which socket's method was called firstly and then returned for both DatagramSocket and MulticastSocket.

Example 1. MulticastSocket's set is returned for DatagramSocket:

import java.io.IOException;
import java.net.*;

public class Test1 {

    public static void main(String[] args) throws IOException {
        System.out.println((new MulticastSocket()).supportedOptions());
        System.out.println((new DatagramSocket()).supportedOptions());
    }
}

Output:

[IP_MULTICAST_IF, SO_SNDBUF, IP_MULTICAST_LOOP, IP_TOS, IP_MULTICAST_TTL, SO_REUSEADDR, SO_RCVBUF]
[IP_MULTICAST_IF, SO_SNDBUF, IP_MULTICAST_LOOP, IP_TOS, IP_MULTICAST_TTL, SO_REUSEADDR, SO_RCVBUF]

Example2 DatagramSocket's set is returned for MulticastSocket: 

import java.io.IOException;
import java.net.*;

public class Test2 {

    public static void main(String[] args) throws IOException {
        System.out.println((new DatagramSocket()).supportedOptions());
        System.out.println((new MulticastSocket()).supportedOptions());
    }
}

Output:
[SO_SNDBUF, IP_TOS, SO_REUSEADDR, SO_RCVBUF]
[SO_SNDBUF, IP_TOS, SO_REUSEADDR, SO_RCVBUF]

Cause: 
DatagramSocket's method supportedOptions() is used for both DatagramSocket and MulticastSocket as second one inherits from the first one.

    public Set<SocketOption<?>> supportedOptions() {
        synchronized(DatagramSocket.class) {
            if (optionsSet) {
                return options;
            }
            try {
                DatagramSocketImpl impl = getImpl();
                options = Collections.unmodifiableSet(impl.supportedOptions());
            } catch (IOException e) {
                options = Collections.emptySet();
            }
            optionsSet = true;
            return options;
        }
    }

 Method cashes options from the first call and doesn't check actual socket type.  

Suggested fix: 
Implement supportedOptions() method in MulticastSocket or add socket type check. 


Comments
Vyom, sorry, I've missed your RFR mail. Thank you for taking care of that!
23-05-2016

Chris, Vyom, now the same problem with cached supported options also affects Socket and ServerSocket. Root case is the same (actually now options are also cached in AbstractSocketImpl and AbstractDatagramSocketImpl). Are you ok if I update this bug's description? Or you'd like to have a separate one for ServerSocket and Socket?
23-05-2016

Silly mistake in the code. MulticastSocket extends DatagramSocket and inherits supportedOptions(). DS caches the supported options set in a static field. MS and DS have different option sets! Either avoid the cache, or cache per MS or DS class.
20-05-2016

Checked latest b118. Situation worsened: now ServerSocket ans Socket are also affected.
20-05-2016

Ilya, no it is new API introduced in jdk 9.
02-12-2015

SQE is forwardporting related tests to JDK 9 see JDK-8136933
01-12-2015