src/java.base/share/classes/java/net/SocketImpl.java
changeset 55102 59567035d279
parent 55081 dd321e3596c0
child 55346 730ed3fc6605
--- a/src/java.base/share/classes/java/net/SocketImpl.java	Wed May 29 22:17:48 2019 -0400
+++ b/src/java.base/share/classes/java/net/SocketImpl.java	Thu May 30 07:19:19 2019 +0100
@@ -25,33 +25,63 @@
 
 package java.net;
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.FileDescriptor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Objects;
 import java.util.Set;
+
+import sun.net.NetProperties;
 import sun.net.PlatformSocketImpl;
+import sun.nio.ch.NioSocketImpl;
 
 /**
  * The abstract class {@code SocketImpl} is a common superclass
  * of all classes that actually implement sockets. It is used to
  * create both client and server sockets.
- * <p>
- * A "plain" socket implements these methods exactly as
- * described, without attempting to go through a firewall or proxy.
+ *
+ * @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.
  *
  * @author  unascribed
  * @since   1.0
  */
 public abstract class SocketImpl implements SocketOptions {
+    private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl();
+
+    private static boolean usePlainSocketImpl() {
+        PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainSocketImpl");
+        String s = AccessController.doPrivileged(pa);
+        return (s != null) && !s.equalsIgnoreCase("false");
+    }
 
     /**
      * Creates an instance of platform's SocketImpl
      */
     @SuppressWarnings("unchecked")
     static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) {
-        return (S) new PlainSocketImpl(server);
+        if (USE_PLAINSOCKETIMPL) {
+            return (S) new PlainSocketImpl(server);
+        } else {
+            return (S) new NioSocketImpl(server);
+        }
     }
 
     /**