--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Tue Nov 22 16:31:03 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Tue Nov 22 19:24:02 2016 -0800
@@ -30,6 +30,7 @@
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.PrintStream;
+import java.net.InetAddress;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -92,7 +93,6 @@
final BiFunction<Snippet, Integer, String> idGenerator;
final List<String> extraRemoteVMOptions;
final List<String> extraCompilerOptions;
- final ExecutionControl.Generator executionControlGenerator;
private int nextKeyIndex = 1;
@@ -102,13 +102,13 @@
private final Map<Subscription, Consumer<SnippetEvent>> keyStatusListeners = new HashMap<>();
private boolean closed = false;
- private ExecutionControl executionControl = null;
+ private final ExecutionControl executionControl;
private SourceCodeAnalysisImpl sourceCodeAnalysis = null;
private static final String L10N_RB_NAME = "jdk.jshell.resources.l10n";
private static ResourceBundle outputRB = null;
- JShell(Builder b) {
+ JShell(Builder b) throws IllegalStateException {
this.in = b.in;
this.out = b.out;
this.err = b.err;
@@ -116,11 +116,18 @@
this.idGenerator = b.idGenerator;
this.extraRemoteVMOptions = b.extraRemoteVMOptions;
this.extraCompilerOptions = b.extraCompilerOptions;
- this.executionControlGenerator = b.executionControlGenerator==null
- ? failOverExecutionControlGenerator(JdiDefaultExecutionControl.launch(),
- JdiDefaultExecutionControl.listen("localhost"),
- JdiDefaultExecutionControl.listen(null))
+ ExecutionControl.Generator executionControlGenerator = b.executionControlGenerator==null
+ ? failOverExecutionControlGenerator(
+ JdiDefaultExecutionControl.listen(InetAddress.getLoopbackAddress().getHostAddress()),
+ JdiDefaultExecutionControl.launch(),
+ JdiDefaultExecutionControl.listen(null)
+ )
: b.executionControlGenerator;
+ try {
+ executionControl = executionControlGenerator.generate(new ExecutionEnvImpl());
+ } catch (Throwable ex) {
+ throw new IllegalStateException("Launching JShell execution engine threw: " + ex.getMessage(), ex);
+ }
this.maps = new SnippetMaps(this);
this.keyMap = new KeyMap(this);
@@ -331,9 +338,10 @@
* functionality. This creates a remote process for execution. It is
* thus important to close the returned instance.
*
+ * @throws IllegalStateException if the {@code JShell} instance could not be created.
* @return the state engine
*/
- public JShell build() {
+ public JShell build() throws IllegalStateException {
return new JShell(this);
}
}
@@ -345,9 +353,10 @@
* That is, create an instance of {@code JShell}.
* <p>
* Equivalent to {@link JShell#builder() JShell.builder()}{@link JShell.Builder#build() .build()}.
+ * @throws IllegalStateException if the {@code JShell} instance could not be created.
* @return an instance of {@code JShell}.
*/
- public static JShell create() {
+ public static JShell create() throws IllegalStateException {
return builder().build();
}
@@ -458,6 +467,7 @@
* Note that the unnamed package is not accessible from the package in which
* {@link JShell#eval(String)} code is placed.
* @param path the path to add to the classpath.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
*/
public void addToClasspath(String path) {
// Compiler
@@ -504,7 +514,11 @@
public void close() {
if (!closed) {
closeDown();
- executionControl().close();
+ try {
+ executionControl().close();
+ } catch (Throwable ex) {
+ // don't care about exceptions on close
+ }
if (sourceCodeAnalysis != null) {
sourceCodeAnalysis.close();
}
@@ -733,14 +747,8 @@
}
// --- private / package-private implementation support ---
+
ExecutionControl executionControl() {
- if (executionControl == null) {
- try {
- executionControl = executionControlGenerator.generate(new ExecutionEnvImpl());
- } catch (Throwable ex) {
- throw new InternalError("Launching execution engine threw: " + ex.getMessage(), ex);
- }
- }
return executionControl;
}