JDK-8224477 : java.net socket types new-style socket option methods - spec and impl mismatch
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 9,10,11,12,13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-05-21
  • Updated: 2019-11-11
  • Resolved: 2019-05-29
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 13 JDK 14
13 b23Fixed 14Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Sub Tasks
JDK-8226643 :  
The scope of this issue has been extended to cover the default
implementation of the three new-style socket option method of
`SocketImpl` and `DatagramSocketImpl`. The associated CSR contains the
specific details. 


The `getOption` and `setOption` methods of the four java.net socket
types ( ServerSocket, Socket, DatagramSocket, and MulticastSocket ),
should conform to their specification. Specifically:

1) Throw NullPointerException if the option name is null.

     * @throws NullPointerException if name is {@code null}

   Example of existing behaviour:
     jshell> (new Socket()).setOption(null, 1);
     |  Exception java.lang.UnsupportedOperationException: unsupported option
     |        at PlainSocketImpl.setOption (PlainSocketImpl.java:72)
     |        at Socket.setOption (Socket.java:1760)
     |        at (#2:1)

2) Throw IllegalArgumentException when passed a bad value.

   A bad value is one of null ( since no specified options accept a
   null value ), or a value outside of the options textually specified
   range, e.g. StandardSocketOptions.SO_SNDBUF specifies "a negative
   size is not allowed". This applied to `setOption` only.

     * @throws IllegalArgumentException if the value is not valid for
     *         the option.

   The options that specify, either explicitly or implicitly, a value
   range (in StandardSocketOptions) are SO_RCVBUF, SO_SNDBUF, IP_TOS,

   Example of existing behaviour:
     jshell> (new Socket()).setOption(StandardSocketOptions.SO_RCVBUF,-1);
     |  Exception java.net.SocketException: bad parameter for SO_SNDBUF or SO_RCVBUF
     |        at AbstractPlainSocketImpl.setOption (AbstractPlainSocketImpl.java:289)
     |        at SocketImpl.setOption (SocketImpl.java:384)
     |        at PlainSocketImpl.setOption (PlainSocketImpl.java:69)
     |        at Socket.setOption (Socket.java:1760)
     |        at (#1:1)

3) Throw an IOException after the socket has been closed. 

     * @throws IOException if an I/O error occurs, or if the socket is closed.

   Example of existing behaviour:
     jshell> var s = new Socket()
     s ==> Socket[unconnected]
     jshell> s.close()
     jshell> s.getOption(StandardSocketOptions.SO_RCVBUF)
     $8 ==> 131072

At least, the NPE part never worked reliably. The throwing of NPE in JDK 9 was because of an implicit check ( an equals invocation for name comparison of extended options ). When the extended options support was refactored, the equals was dropped. NPE was never thrown on Windows, not even in JDK 9. $ uname -a CYGWIN_NT-6.3 llg00dtu 2.7.0(0.306/5/3) 2017-02-12 13:18 x86_64 Cygwin $ cat Test.java import java.net.*; public class Test { public static void main(String[] args) throws Exception { (new Socket()).getOption(null); } } $ ./jdk-9/bin/java Test Exception in thread "main" java.lang.UnsupportedOperationException: unsupported option at java.base/java.net.SocketImpl.getOption(SocketImpl.java:442) at java.base/java.net.Socket.getOption(Socket.java:1789) at Test.main(Test.java:4)

[~alanb] Yes, the test is new in 13.

There are a couple of cases where the Socket.setOption method will throw the wrong exception when using the legacy SocketImpl. These issues do not exist with the new SocketImpl (JEP 353) (but will course re-appear when running with -Djdk.net.usePlainSocketImpl). The setOption(null, null) issue seems to be a regression. JDK 9 throws the expected NPE, JDK 11 throws UOE. I assume the test that is catching this issue now is new as the mismatch between spec and implementation has been there for a few releases.