JDK-8222028 : Reimplement the Legacy Socket API
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2019-04-05
  • Updated: 2019-05-09
  • Resolved: 2019-05-05
Related Reports
CSR :  
Description
Summary
-------

Replace the underlying implementation used by the `java.net.Socket` and `java.net.ServerSocket` APIs with a simpler and more modern implementation that is easy to maintain and debug. The new implementation will be easy to adapt to work with user-mode threads, a.k.a. fibers, currently being explored in [Project Loom](https://openjdk.java.net/projects/loom).

Problem
-------

The `java.net.Socket` and `java.net.ServerSocket` APIs, and their underlying implementation, date back to JDK 1.0. The implementation is a mix of legacy Java and C code that is painful to maintain and debug. In the context of a future world of fibers that park instead of blocking threads in native methods, the current implementation is not fit for purpose.

Solution
--------

The `java.net.Socket` and `java.net.ServerSocket` APIs delegate all socket operations to a  `java.net.SocketImpl`, a Service Provider Interface (SPI) mechanism that has existed since JDK 1.0. The built-in implementation is termed the ���plain��� implementation, implemented by the non-public `PlainSocketImpl` with supporting classes `SocketInputStream` and `SocketOutputStream`.

The new implementation, `NioSocketImpl`, is a drop-in replacement for `PlainSocketImpl`. It is developed to be easy to maintain and debug. It shares the same JDK-internal infrastructure as the New I/O (NIO) implementation so it doesn't need its own native code. It integrates with the existing buffer cache mechanism so that it doesn���t need to use the thread stack for I/O. It uses `java.util.concurrent` locks rather than `synchronized` methods so that it can play well with fibers in the future. In JDK 11, the NIO `SocketChannel` and the other `SelectableChannel` implementations were mostly re-implemented with the same goal in mind.

To reduce the risk of switching the implementation after more than twenty years, the old implementation will not be removed. A system property is added to configure the JDK to use the old implementation. This can be used in environments where older code is found to have a dependency on unspecified behavior that differs between the old and new implementation. The property can also be set in the JDK's network configuration file for environments that cannot specify the property on the command line. Some future release will remove the old implementation and the property.


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

There are no Java SE specification changes. A number of API issues were identified during the development of this feature and these are being addressed by other issues, e.g. JDK-8219446.

The JDK-specific system property to select the old implementation is `jdk.net.usePlainSocketImpl`. If set, or set to the value `true`, at startup, then the old implementation will be used. The property can also be set in the network configuration file (`$JAVA_HOME/conf/net.properties`) for end-user or other environments that are unable to set the property on the command line. If the system property is set, and also set in the network configuration file, then the system property wins.

In addition, an implementation note will be added to the `SocketImpl` class description:

```
@implNote Client and server sockets created with the {@code Socket} and
{@code SocketServer} public constructors create a system-default
{@code SocketImpl}. The JDK historically used a {@code SocketImpl}
implementation type named "PlainSocketImpl" that has since been replaced by a
newer implementation. The JDK continues to ship with the older implementation
to allow code to run that depends on unspecified behavior that differs between
the old and new implementations. The old implementation will be used if the
Java virtual machine is started with the system property {@systemProperty
jdk.net.usePlainSocketImpl} set to use the old implementation. It may also be
set in the JDK's network configuration file, located in {@code
${java.home}/conf/net.properties}. The value of the property is the string
representation of a boolean. If set without a value then it defaults to {@code
true}, hence running with {@code -Djdk.net.usePlainSocketImpl} or {@code
-Djdk.net.usePlainSocketImpl=true} will configure the Java virtual machine
to use the old implementation. The property and old implementation will be
removed in a future version.
```

Comments
Thanks for the update and explanation Alan; no re-review needed.
09-05-2019

I've updated the implNote in the CSR to align with the updated text that we agreed in the code review. As an implNote is non-normative then I assume the CSR does not need to be re-submitted.
09-05-2019

Moving to Approved.
05-05-2019

The system property is purely for transition from the old to new SocketImpl and it will be removed once the new implementation has proved itself. We hope it will not be needed and no plan for the JDK to ship with any other implementations.
07-04-2019

If more than two SocketImpl implementations are expected, then having the system property take a name rather than a boolean would be more flexible, but that doesn't seem necessary in this case.
06-04-2019

Moving to Provisional.
06-04-2019