8164518: JShell: Add failover case of explicitly listening to "localhost"
authorrfield
Wed, 31 Aug 2016 10:35:51 -0700
changeset 40764 29ded021f809
parent 40763 209113892b0d
child 40765 6f9556cf4404
8164518: JShell: Add failover case of explicitly listening to "localhost" Reviewed-by: jlahoda
langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIDefaultExecutionControl.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIInitiator.java
langtools/test/jdk/jshell/JDILaunchingExecutionControlTest.java
langtools/test/jdk/jshell/JDIListeningExecutionControlTest.java
langtools/test/jdk/jshell/JDIListeningLocalhostExecutionControlTest.java
langtools/test/jdk/jshell/UserJDIUserRemoteTest.java
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Tue Aug 30 20:49:41 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Wed Aug 31 10:35:51 2016 -0700
@@ -51,8 +51,6 @@
 import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
 import jdk.jshell.spi.ExecutionEnv;
 import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
-import static java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.toList;
 import static jdk.jshell.Util.expunge;
 
 /**
@@ -120,7 +118,8 @@
         this.executionControlGenerator = b.executionControlGenerator==null
                 ? failOverExecutionControlGenerator(
                         JDIDefaultExecutionControl.launch(),
-                        JDIDefaultExecutionControl.listen())
+                        JDIDefaultExecutionControl.listen("localhost"),
+                        JDIDefaultExecutionControl.listen(null))
                 : b.executionControlGenerator;
 
         this.maps = new SnippetMaps(this);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIDefaultExecutionControl.java	Tue Aug 30 20:49:41 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIDefaultExecutionControl.java	Wed Aug 31 10:35:51 2016 -0700
@@ -77,17 +77,19 @@
      * @return the generator
      */
     public static ExecutionControl.Generator launch() {
-        return env -> create(env, true);
+        return env -> create(env, true, null);
     }
 
     /**
      * Creates an ExecutionControl instance based on a JDI
      * {@code ListeningConnector}.
      *
+     * @param host explicit hostname to use, if null use discovered
+     * hostname, applies to listening only (!isLaunch)
      * @return the generator
      */
-    public static ExecutionControl.Generator listen() {
-        return env -> create(env, false);
+    public static ExecutionControl.Generator listen(String host) {
+        return env -> create(env, false, host);
     }
 
     /**
@@ -100,10 +102,15 @@
      *
      * @param env the context passed by
      * {@link jdk.jshell.spi.ExecutionControl#start(jdk.jshell.spi.ExecutionEnv) }
+     * @param isLaunch does JDI do the launch? That is, LaunchingConnector,
+     * otherwise we start explicitly and use ListeningConnector
+     * @param host explicit hostname to use, if null use discovered
+     * hostname, applies to listening only (!isLaunch)
      * @return the channel
      * @throws IOException if there are errors in set-up
      */
-    private static JDIDefaultExecutionControl create(ExecutionEnv env, boolean isLaunch) throws IOException {
+    private static JDIDefaultExecutionControl create(ExecutionEnv env,
+            boolean isLaunch, String host) throws IOException {
         try (final ServerSocket listener = new ServerSocket(0)) {
             // timeout after 60 seconds
             listener.setSoTimeout(60000);
@@ -111,7 +118,7 @@
 
             // Set-up the JDI connection
             JDIInitiator jdii = new JDIInitiator(port,
-                    env.extraRemoteVMOptions(), REMOTE_AGENT, isLaunch);
+                    env.extraRemoteVMOptions(), REMOTE_AGENT, isLaunch, host);
             VirtualMachine vm = jdii.vm();
             Process process = jdii.process();
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIInitiator.java	Tue Aug 30 20:49:41 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIInitiator.java	Wed Aug 31 10:35:51 2016 -0700
@@ -56,9 +56,11 @@
      * @param remoteAgent full class name of remote agent to launch
      * @param isLaunch does JDI do the launch? That is, LaunchingConnector,
      * otherwise we start explicitly and use ListeningConnector
+     * @param host explicit hostname to use, if null use discovered
+     * hostname, applies to listening only (!isLaunch)
      */
-    public JDIInitiator(int port, List<String> remoteVMOptions,
-            String remoteAgent, boolean isLaunch) {
+    public JDIInitiator(int port, List<String> remoteVMOptions, String remoteAgent,
+            boolean isLaunch, String host) {
         this.remoteAgent = remoteAgent;
         String connectorName
                 = isLaunch
@@ -72,6 +74,9 @@
                 = isLaunch
                         ? launchArgs(port, String.join(" ", remoteVMOptions))
                         : new HashMap<>();
+        if (host != null && !isLaunch) {
+            argumentName2Value.put("localAddress", host);
+        }
         this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value);
         this.vm = isLaunch
                 ? launchTarget()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JDILaunchingExecutionControlTest.java	Wed Aug 31 10:35:51 2016 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164518
+ * @summary Tests for standard JDI connector (without failover) -- launching
+ * @modules jdk.jshell/jdk.jshell.execution
+ * @build KullaTesting ExecutionControlTestBase
+ * @run testng JDILaunchingExecutionControlTest
+ */
+
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import jdk.jshell.execution.JDIDefaultExecutionControl;
+
+@Test
+public class JDILaunchingExecutionControlTest extends ExecutionControlTestBase {
+
+    @BeforeMethod
+    @Override
+    public void setUp() {
+        setUp(builder -> builder.executionEngine(JDIDefaultExecutionControl.launch()));
+    }
+}
--- a/langtools/test/jdk/jshell/JDIListeningExecutionControlTest.java	Tue Aug 30 20:49:41 2016 -0700
+++ b/langtools/test/jdk/jshell/JDIListeningExecutionControlTest.java	Wed Aug 31 10:35:51 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8131029 8159935 8160127
+ * @bug 8131029 8159935 8160127 8164518
  * @summary Tests for alternate JDI connector -- listening
  * @modules jdk.jshell/jdk.jshell.execution
  * @build KullaTesting ExecutionControlTestBase
@@ -41,6 +41,6 @@
     @BeforeMethod
     @Override
     public void setUp() {
-        setUp(builder -> builder.executionEngine(JDIDefaultExecutionControl.listen()));
+        setUp(builder -> builder.executionEngine(JDIDefaultExecutionControl.listen(null)));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JDIListeningLocalhostExecutionControlTest.java	Wed Aug 31 10:35:51 2016 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164518
+ * @summary Tests for alternate JDI connector -- listening to "localhost"
+ * @modules jdk.jshell/jdk.jshell.execution
+ * @build KullaTesting ExecutionControlTestBase
+ * @run testng JDIListeningLocalhostExecutionControlTest
+ */
+
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import jdk.jshell.execution.JDIDefaultExecutionControl;
+
+@Test
+public class JDIListeningLocalhostExecutionControlTest extends ExecutionControlTestBase {
+
+    @BeforeMethod
+    @Override
+    public void setUp() {
+        setUp(builder -> builder.executionEngine(JDIDefaultExecutionControl.listen("localhost")));
+    }
+}
--- a/langtools/test/jdk/jshell/UserJDIUserRemoteTest.java	Tue Aug 30 20:49:41 2016 -0700
+++ b/langtools/test/jdk/jshell/UserJDIUserRemoteTest.java	Wed Aug 31 10:35:51 2016 -0700
@@ -159,7 +159,7 @@
                     + System.getProperty("path.separator")
                     + System.getProperty("user.dir"));
             JDIInitiator jdii = new JDIInitiator(port,
-                    opts, REMOTE_AGENT, true);
+                    opts, REMOTE_AGENT, true, null);
             VirtualMachine vm = jdii.vm();
             Process process = jdii.process();