8131023: JShell: System.in does not work
Summary: Pass user input to snippets/remote agent
Reviewed-by: rfield
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Thu Sep 01 10:30:50 2016 +0200
@@ -57,6 +57,8 @@
import jdk.internal.jline.console.KeyMap;
import jdk.internal.jline.console.UserInterruptException;
import jdk.internal.jline.console.completer.Completer;
+import jdk.internal.jline.console.history.History;
+import jdk.internal.jline.console.history.MemoryHistory;
import jdk.internal.jline.extra.EditingHistory;
import jdk.internal.jshell.tool.StopDetectingInputStream.State;
@@ -68,6 +70,7 @@
final StopDetectingInputStream input;
final ConsoleReader in;
final EditingHistory history;
+ final MemoryHistory userInputHistory = new MemoryHistory();
String prefix = "";
@@ -299,6 +302,9 @@
}
public void beforeUserCode() {
+ synchronized (this) {
+ inputBytes = null;
+ }
input.setState(State.BUFFER);
}
@@ -380,6 +386,36 @@
}
}
+ private byte[] inputBytes;
+ private int inputBytesPointer;
+
+ @Override
+ public synchronized int readUserInput() {
+ while (inputBytes == null || inputBytes.length <= inputBytesPointer) {
+ boolean prevHandleUserInterrupt = in.getHandleUserInterrupt();
+ History prevHistory = in.getHistory();
+
+ try {
+ input.setState(State.WAIT);
+ in.setHandleUserInterrupt(true);
+ in.setHistory(userInputHistory);
+ inputBytes = (in.readLine("") + System.getProperty("line.separator")).getBytes();
+ inputBytesPointer = 0;
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ return -1;
+ } catch (UserInterruptException ex) {
+ repl.state.stop();
+ return -1;
+ } finally {
+ in.setHistory(prevHistory);
+ in.setHandleUserInterrupt(prevHandleUserInterrupt);
+ input.setState(State.BUFFER);
+ }
+ }
+ return inputBytes[inputBytesPointer++];
+ }
+
/**
* A possible action which the user can choose to perform.
*/
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Thu Sep 01 10:30:50 2016 +0200
@@ -54,6 +54,8 @@
public abstract void replaceLastHistoryEntry(String source);
+ public abstract int readUserInput();
+
class InputInterruptedException extends Exception {
private static final long serialVersionUID = 1L;
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Sep 01 10:30:50 2016 +0200
@@ -26,7 +26,6 @@
package jdk.internal.jshell.tool;
import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
@@ -142,11 +141,30 @@
/**
* The constructor for the tool (used by tool launch via main and by test
* harnesses to capture ins and outs.
+ * @param in command line input -- snippets, commands and user input
+ * @param cmdout command line output, feedback including errors
+ * @param cmderr start-up errors and debugging info
+ * @param console console control interaction
+ * @param userout code execution output -- System.out.printf("hi")
+ * @param usererr code execution error stream -- System.err.printf("Oops")
+ * @param prefs preferences to use
+ * @param locale locale to use
+ */
+ public JShellTool(InputStream in, PrintStream cmdout, PrintStream cmderr,
+ PrintStream console,
+ PrintStream userout, PrintStream usererr,
+ Preferences prefs, Locale locale) {
+ this(in, cmdout, cmderr, console, null, userout, usererr, prefs, locale);
+ }
+
+ /**
+ * The constructor for the tool (used by tool launch via main and by test
+ * harnesses to capture ins and outs.
* @param cmdin command line input -- snippets and commands
* @param cmdout command line output, feedback including errors
* @param cmderr start-up errors and debugging info
* @param console console control interaction
- * @param userin code execution input (not yet functional)
+ * @param userin code execution input, or null to use IOContext
* @param userout code execution output -- System.out.printf("hi")
* @param usererr code execution error stream -- System.err.printf("Oops")
* @param prefs preferences to use
@@ -160,7 +178,12 @@
this.cmdout = cmdout;
this.cmderr = cmderr;
this.console = console;
- this.userin = userin;
+ this.userin = userin != null ? userin : new InputStream() {
+ @Override
+ public int read() throws IOException {
+ return input.readUserInput();
+ }
+ };
this.userout = userout;
this.usererr = usererr;
this.prefs = prefs;
@@ -452,7 +475,7 @@
*/
public static void main(String[] args) throws Exception {
new JShellTool(System.in, System.out, System.err, System.out,
- new ByteArrayInputStream(new byte[0]), System.out, System.err,
+ System.out, System.err,
Preferences.userRoot().node("tool/JShell"),
Locale.getDefault())
.start(args);
@@ -2621,6 +2644,11 @@
public void close() {
scannerIn.close();
}
+
+ @Override
+ public int readUserInput() {
+ return -1;
+ }
}
class FileScannerIOContext extends ScannerIOContext {
@@ -2659,4 +2687,9 @@
@Override
public void close() {
}
+
+ @Override
+ public int readUserInput() {
+ return -1;
+ }
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DemultiplexInput.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DemultiplexInput.java Thu Sep 01 10:30:50 2016 +0200
@@ -40,15 +40,14 @@
class DemultiplexInput extends Thread {
private final DataInputStream delegate;
- private final PipeInputStream command;
private final Map<String, OutputStream> io;
+ private final Iterable<OutputStream> closeList;
- DemultiplexInput(InputStream input, PipeInputStream command,
- Map<String, OutputStream> io) {
+ DemultiplexInput(InputStream input, Map<String, OutputStream> io, Iterable<OutputStream> closeList) {
super("output reader");
this.delegate = new DataInputStream(input);
- this.command = command;
this.io = io;
+ this.closeList = closeList;
}
@Override
@@ -65,23 +64,23 @@
byte[] data = new byte[dataLen];
DemultiplexInput.this.delegate.readFully(data);
String chan = new String(name, "UTF-8");
- if (chan.equals("command")) {
- for (byte b : data) {
- command.write(Byte.toUnsignedInt(b));
- }
+ OutputStream out = io.get(chan);
+ if (out == null) {
+ debug("Unexpected channel name: %s", chan);
} else {
- OutputStream out = io.get(chan);
- if (out == null) {
- debug("Unexpected channel name: %s", chan);
- } else {
- out.write(data);
- }
+ out.write(data);
}
}
} catch (IOException ex) {
debug(ex, "Failed reading output");
} finally {
- command.close();
+ for (OutputStream out : closeList) {
+ try {
+ out.close();
+ } catch (IOException ex) {
+ debug(ex, "Failed reading output");
+ }
+ }
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIDefaultExecutionControl.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JDIDefaultExecutionControl.java Thu Sep 01 10:30:50 2016 +0200
@@ -25,9 +25,9 @@
package jdk.jshell.execution;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
@@ -48,7 +48,7 @@
import com.sun.jdi.VirtualMachine;
import jdk.jshell.spi.ExecutionControl;
import jdk.jshell.spi.ExecutionEnv;
-import static jdk.jshell.execution.Util.remoteInput;
+import static jdk.jshell.execution.Util.remoteInputOutput;
/**
* The implementation of {@link jdk.jshell.spi.ExecutionControl} that the
@@ -109,7 +109,7 @@
* @return the channel
* @throws IOException if there are errors in set-up
*/
- private static JDIDefaultExecutionControl create(ExecutionEnv env,
+ private static ExecutionControl create(ExecutionEnv env,
boolean isLaunch, String host) throws IOException {
try (final ServerSocket listener = new ServerSocket(0)) {
// timeout after 60 seconds
@@ -122,10 +122,6 @@
VirtualMachine vm = jdii.vm();
Process process = jdii.process();
- // Forward input to the remote agent
- Util.forwardInputToRemote(env.userIn(), process.getOutputStream(),
- ex -> debug(ex, "input forwarding failure"));
-
List<Consumer<String>> deathListeners = new ArrayList<>();
deathListeners.add(s -> env.closeDown());
Util.detectJDIExitEvent(vm, s -> {
@@ -138,12 +134,13 @@
// output.
Socket socket = listener.accept();
// out before in -- match remote creation so we don't hang
- ObjectOutput cmdout = new ObjectOutputStream(socket.getOutputStream());
- Map<String, OutputStream> io = new HashMap<>();
- io.put("out", env.userOut());
- io.put("err", env.userErr());
- ObjectInput cmdin = remoteInput(socket.getInputStream(), io);
- return new JDIDefaultExecutionControl(cmdout, cmdin, vm, process, deathListeners);
+ OutputStream out = socket.getOutputStream();
+ Map<String, OutputStream> outputs = new HashMap<>();
+ outputs.put("out", env.userOut());
+ outputs.put("err", env.userErr());
+ Map<String, InputStream> input = new HashMap<>();
+ input.put("in", env.userIn());
+ return remoteInputOutput(socket.getInputStream(), out, outputs, input, (objIn, objOut) -> new JDIDefaultExecutionControl(objOut, objIn, vm, process, deathListeners));
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/MultiplexingOutputStream.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/MultiplexingOutputStream.java Thu Sep 01 10:30:50 2016 +0200
@@ -50,13 +50,7 @@
@Override
public void write(int b) throws IOException {
- synchronized (delegate) {
- delegate.write(name.length); //assuming the len is small enough to fit into byte
- delegate.write(name);
- delegate.write(1);
- delegate.write(b);
- delegate.flush();
- }
+ write(new byte[] {(byte) b});
}
@Override
@@ -65,10 +59,12 @@
int i = 0;
while (len > 0) {
int size = Math.min(PACKET_SIZE, len);
- delegate.write(name.length); //assuming the len is small enough to fit into byte
- delegate.write(name);
- delegate.write(size);
- delegate.write(b, off + i, size);
+ byte[] data = new byte[name.length + 1 + size + 1];
+ data[0] = (byte) name.length; //assuming the len is small enough to fit into byte
+ System.arraycopy(name, 0, data, 1, name.length);
+ data[name.length + 1] = (byte) size;
+ System.arraycopy(b, off + i, data, name.length + 2, size);
+ delegate.write(data);
i += size;
len -= size;
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java Thu Sep 01 10:30:50 2016 +0200
@@ -24,7 +24,9 @@
*/
package jdk.jshell.execution;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
/**
*
@@ -39,7 +41,10 @@
private boolean closed;
@Override
- public synchronized int read() {
+ public synchronized int read() throws IOException {
+ if (start == end) {
+ inputNeeded();
+ }
while (start == end) {
if (closed) {
return -1;
@@ -57,7 +62,9 @@
}
}
- public synchronized void write(int b) {
+ protected void inputNeeded() throws IOException {}
+
+ private synchronized void write(int b) {
if (closed) {
throw new IllegalStateException("Already closed.");
}
@@ -85,4 +92,22 @@
notifyAll();
}
+ public OutputStream createOutput() {
+ return new OutputStream() {
+ @Override public void write(int b) throws IOException {
+ PipeInputStream.this.write(b);
+ }
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ for (int i = 0 ; i < len ; i++) {
+ write(Byte.toUnsignedInt(b[off + i]));
+ }
+ }
+ @Override
+ public void close() throws IOException {
+ PipeInputStream.this.close();
+ }
+ };
+ }
+
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/RemoteExecutionControl.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/RemoteExecutionControl.java Thu Sep 01 10:30:50 2016 +0200
@@ -61,10 +61,12 @@
Socket socket = new Socket(loopBack, Integer.parseInt(args[0]));
InputStream inStream = socket.getInputStream();
OutputStream outStream = socket.getOutputStream();
- Map<String, Consumer<OutputStream>> chans = new HashMap<>();
- chans.put("out", st -> System.setOut(new PrintStream(st, true)));
- chans.put("err", st -> System.setErr(new PrintStream(st, true)));
- forwardExecutionControlAndIO(new RemoteExecutionControl(), inStream, outStream, chans);
+ Map<String, Consumer<OutputStream>> outputs = new HashMap<>();
+ outputs.put("out", st -> System.setOut(new PrintStream(st, true)));
+ outputs.put("err", st -> System.setErr(new PrintStream(st, true)));
+ Map<String, Consumer<InputStream>> input = new HashMap<>();
+ input.put("in", st -> System.setIn(st));
+ forwardExecutionControlAndIO(new RemoteExecutionControl(), inStream, outStream, outputs, input);
}
// These three variables are used by the main JShell process in interrupting
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Thu Sep 01 10:30:50 2016 +0200
@@ -25,6 +25,7 @@
package jdk.jshell.execution;
import jdk.jshell.spi.ExecutionEnv;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
@@ -32,9 +33,13 @@
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
+
import com.sun.jdi.VirtualMachine;
import jdk.jshell.spi.ExecutionControl;
@@ -99,21 +104,40 @@
* instance, then responses back on the output.
* @param ec the direct instance of {@link ExecutionControl} to process commands
* @param inStream the stream from which to create the command input
- * @param outStream the stream that will carry {@code System.out},
- * {@code System.err}, any specified auxiliary channels, and the
- * command response output.
- * @param streamMap a map between names of additional streams to carry and setters
- * for the stream
+ * @param outStream the stream that will carry any specified auxiliary channels (like
+ * {@code System.out} and {@code System.err}), and the command response output.
+ * @param outputStreamMap a map between names of additional streams to carry and setters
+ * for the stream. Names starting with '$' are reserved for internal use.
+ * @param inputStreamMap a map between names of additional streams to carry and setters
+ * for the stream. Names starting with '$' are reserved for internal use.
* @throws IOException if there are errors using the passed streams
*/
public static void forwardExecutionControlAndIO(ExecutionControl ec,
InputStream inStream, OutputStream outStream,
- Map<String, Consumer<OutputStream>> streamMap) throws IOException {
- ObjectInputStream cmdIn = new ObjectInputStream(inStream);
- for (Entry<String, Consumer<OutputStream>> e : streamMap.entrySet()) {
+ Map<String, Consumer<OutputStream>> outputStreamMap,
+ Map<String, Consumer<InputStream>> inputStreamMap) throws IOException {
+ for (Entry<String, Consumer<OutputStream>> e : outputStreamMap.entrySet()) {
e.getValue().accept(multiplexingOutputStream(e.getKey(), outStream));
}
- ObjectOutputStream cmdOut = new ObjectOutputStream(multiplexingOutputStream("command", outStream));
+
+ ObjectOutputStream cmdOut = new ObjectOutputStream(multiplexingOutputStream("$command", outStream));
+ PipeInputStream cmdInPipe = new PipeInputStream();
+ Map<String, OutputStream> inputs = new HashMap<>();
+ inputs.put("$command", cmdInPipe.createOutput());
+ for (Entry<String, Consumer<InputStream>> e : inputStreamMap.entrySet()) {
+ OutputStream inputSignal = multiplexingOutputStream("$" + e.getKey() + "-input-requested", outStream);
+ PipeInputStream inputPipe = new PipeInputStream() {
+ @Override protected void inputNeeded() throws IOException {
+ inputSignal.write('1');
+ inputSignal.flush();
+ }
+ };
+ inputs.put(e.getKey(), inputPipe.createOutput());
+ e.getValue().accept(inputPipe);
+ }
+ new DemultiplexInput(inStream, inputs, inputs.values()).start();
+ ObjectInputStream cmdIn = new ObjectInputStream(cmdInPipe);
+
forwardExecutionControl(ec, cmdIn, cmdOut);
}
@@ -122,18 +146,41 @@
}
/**
- * Reads from an InputStream which has been packetized and write its contents
- * to the out and err OutputStreams; Copies the command stream.
+ * Creates an ExecutionControl for given packetized input and output. The given InputStream
+ * is de-packetized, and content forwarded to ObjectInput and given OutputStreams. The ObjectOutput
+ * and values read from the given InputStream are packetized and sent to the given OutputStream.
+ *
* @param input the packetized input stream
- * @param streamMap a map between stream names and the output streams to forward
- * @return the command stream
+ * @param output the packetized output stream
+ * @param outputStreamMap a map between stream names and the output streams to forward.
+ * Names starting with '$' are reserved for internal use.
+ * @param inputStreamMap a map between stream names and the input streams to forward.
+ * Names starting with '$' are reserved for internal use.
+ * @param factory to create the ExecutionControl from ObjectInput and ObjectOutput.
+ * @return the created ExecutionControl
* @throws IOException if setting up the streams raised an exception
*/
- public static ObjectInput remoteInput(InputStream input,
- Map<String, OutputStream> streamMap) throws IOException {
+ public static ExecutionControl remoteInputOutput(InputStream input, OutputStream output,
+ Map<String, OutputStream> outputStreamMap, Map<String, InputStream> inputStreamMap,
+ BiFunction<ObjectInput, ObjectOutput, ExecutionControl> factory) throws IOException {
+ Map<String, OutputStream> augmentedStreamMap = new HashMap<>(outputStreamMap);
+ ObjectOutput commandOut = new ObjectOutputStream(Util.multiplexingOutputStream("$command", output));
+ for (Entry<String, InputStream> e : inputStreamMap.entrySet()) {
+ InputStream in = e.getValue();
+ OutputStream inTarget = Util.multiplexingOutputStream(e.getKey(), output);
+ augmentedStreamMap.put("$" + e.getKey() + "-input-requested", new OutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ //value ignored, just a trigger to read from the input
+ inTarget.write(in.read());
+ }
+ });
+ }
PipeInputStream commandIn = new PipeInputStream();
- new DemultiplexInput(input, commandIn, streamMap).start();
- return new ObjectInputStream(commandIn);
+ OutputStream commandInTarget = commandIn.createOutput();
+ augmentedStreamMap.put("$command", commandInTarget);
+ new DemultiplexInput(input, augmentedStreamMap, Arrays.asList(commandInTarget)).start();
+ return factory.apply(new ObjectInputStream(commandIn), commandOut);
}
/**
@@ -151,32 +198,4 @@
}
}
- /**
- * Creates a Thread that will ship all input to the remote agent.
- *
- * @param inputStream the user input
- * @param outStream the input to the remote agent
- * @param handler a failure handler
- */
- public static void forwardInputToRemote(final InputStream inputStream,
- final OutputStream outStream, final Consumer<Exception> handler) {
- Thread thr = new Thread("input reader") {
- @Override
- public void run() {
- try {
- byte[] buf = new byte[256];
- int cnt;
- while ((cnt = inputStream.read(buf)) != -1) {
- outStream.write(buf, 0, cnt);
- outStream.flush();
- }
- } catch (Exception ex) {
- handler.accept(ex);
- }
- }
- };
- thr.setPriority(Thread.MAX_PRIORITY - 1);
- thr.start();
- }
-
}
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Thu Sep 01 10:30:50 2016 +0200
@@ -247,7 +247,6 @@
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
- userin,
new PrintStream(userout),
new PrintStream(usererr),
prefs,
@@ -463,7 +462,7 @@
private List<String> computeCompletions(String code, boolean isSmart) {
JShellTool js = this.repl != null ? this.repl
- : new JShellTool(null, null, null, null, null, null, null, prefs, Locale.ROOT);
+ : new JShellTool(null, null, null, null, null, null, prefs, Locale.ROOT);
int cursor = code.indexOf('|');
code = code.replace("|", "");
assertTrue(cursor > -1, "'|' not found: " + code);
--- a/langtools/test/jdk/jshell/StartOptionTest.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/test/jdk/jshell/StartOptionTest.java Thu Sep 01 10:30:50 2016 +0200
@@ -63,7 +63,6 @@
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
- new TestingInputStream(),
new PrintStream(userout),
new PrintStream(usererr),
new ReplToolTesting.MemoryPreferences(),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/UserInputTest.java Thu Sep 01 10:30:50 2016 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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 8131023
+ * @summary Verify that the user's code can read System.in
+ * @build KullaTesting TestingInputStream
+ * @run testng UserInputTest
+ */
+
+import org.testng.annotations.Test;
+
+@Test
+public class UserInputTest extends KullaTesting {
+
+ public void testReadInput() {
+ setInput("AB\n");
+ assertEval("System.in.read()", "65");
+ setInput("BC\n");
+ assertEval("System.in.read()", "66");
+ }
+
+}
--- a/langtools/test/jdk/jshell/UserJDIUserRemoteTest.java Thu Sep 01 13:18:42 2016 +0800
+++ b/langtools/test/jdk/jshell/UserJDIUserRemoteTest.java Thu Sep 01 10:30:50 2016 +0200
@@ -37,7 +37,6 @@
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
@@ -62,7 +61,7 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import static jdk.jshell.execution.Util.forwardExecutionControlAndIO;
-import static jdk.jshell.execution.Util.remoteInput;
+import static jdk.jshell.execution.Util.remoteInputOutput;
@Test
public class UserJDIUserRemoteTest extends ExecutionControlTestBase {
@@ -146,7 +145,7 @@
* @return the channel
* @throws IOException if there are errors in set-up
*/
- static MyExecutionControl make(ExecutionEnv env, UserJDIUserRemoteTest test) throws IOException {
+ static ExecutionControl make(ExecutionEnv env, UserJDIUserRemoteTest test) throws IOException {
try (final ServerSocket listener = new ServerSocket(0)) {
// timeout after 60 seconds
listener.setSoTimeout(60000);
@@ -175,13 +174,14 @@
// output.
Socket socket = listener.accept();
// out before in -- match remote creation so we don't hang
- ObjectOutput cmdout = new ObjectOutputStream(socket.getOutputStream());
- Map<String, OutputStream> io = new HashMap<>();
- io.put("out", env.userOut());
- io.put("err", env.userErr());
- io.put("aux", test.auxStream);
- ObjectInput cmdin = remoteInput(socket.getInputStream(), io);
- MyExecutionControl myec = new MyExecutionControl(cmdout, cmdin, vm, process, deathListeners);
+ OutputStream out = socket.getOutputStream();
+ Map<String, OutputStream> outputs = new HashMap<>();
+ outputs.put("out", env.userOut());
+ outputs.put("err", env.userErr());
+ outputs.put("aux", test.auxStream);
+ Map<String, InputStream> input = new HashMap<>();
+ input.put("in", env.userIn());
+ ExecutionControl myec = remoteInputOutput(socket.getInputStream(), out, outputs, input, (objIn, objOut) -> new MyExecutionControl(objOut, objIn, vm, process, deathListeners));
test.currentEC = myec;
return myec;
}
@@ -255,11 +255,13 @@
Socket socket = new Socket(loopBack, Integer.parseInt(args[0]));
InputStream inStream = socket.getInputStream();
OutputStream outStream = socket.getOutputStream();
- Map<String, Consumer<OutputStream>> chans = new HashMap<>();
- chans.put("out", st -> System.setOut(new PrintStream(st, true)));
- chans.put("err", st -> System.setErr(new PrintStream(st, true)));
- chans.put("aux", st -> { auxPrint = new PrintStream(st, true); });
- forwardExecutionControlAndIO(new MyRemoteExecutionControl(), inStream, outStream, chans);
+ Map<String, Consumer<OutputStream>> outputs = new HashMap<>();
+ outputs.put("out", st -> System.setOut(new PrintStream(st, true)));
+ outputs.put("err", st -> System.setErr(new PrintStream(st, true)));
+ outputs.put("aux", st -> { auxPrint = new PrintStream(st, true); });
+ Map<String, Consumer<InputStream>> input = new HashMap<>();
+ input.put("in", st -> System.setIn(st));
+ forwardExecutionControlAndIO(new MyRemoteExecutionControl(), inStream, outStream, outputs, input);
} catch (Throwable ex) {
throw ex;
}