langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/jdi/JDIConnection.java
author rfield
Thu, 02 Jun 2016 14:05:13 -0700
changeset 38836 b09d1cfbf28c
parent 38608 691b607bbcd6
permissions -rw-r--r--
8131029: JShell: recover from VMConnection launch failure Reviewed-by: vromero
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     1
/*
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
     2
 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     4
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    10
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    15
 * accompanied this code).
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    16
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    20
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    23
 * questions.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    24
 */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    25
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    26
/*
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    27
 * This source code is provided to illustrate the usage of a given feature
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    28
 * or technique and has been deliberately simplified. Additional steps
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    29
 * required for a production-quality application, such as security checks,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    30
 * input validation and proper error handling, might not be present in
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    31
 * this sample code.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    32
 */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    33
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    34
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
    35
package jdk.internal.jshell.jdi;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    36
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    37
import com.sun.jdi.*;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    38
import com.sun.jdi.connect.*;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    39
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    40
import java.util.*;
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    41
import java.util.Map.Entry;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    42
import java.io.*;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    43
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    44
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    45
/**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    46
 * Connection to a Java Debug Interface VirtualMachine instance.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    47
 * Adapted from jdb VMConnection. Message handling, exception handling, and I/O
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    48
 * redirection changed.  Interface to JShell added.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    49
 */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    50
class JDIConnection {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    51
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
    52
    private static final String REMOTE_AGENT = "jdk.internal.jshell.remote.RemoteAgent";
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
    53
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    54
    private VirtualMachine vm;
38608
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
    55
    private boolean active = true;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    56
    private Process process = null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    57
    private int outputCompleteCount = 0;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    58
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
    59
    private final JDIExecutionControl ec;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    60
    private final Connector connector;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    61
    private final Map<String, com.sun.jdi.connect.Connector.Argument> connectorArgs;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    62
    private final int traceFlags;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    63
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
    64
    private synchronized void notifyOutputComplete() {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    65
        outputCompleteCount++;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    66
        notifyAll();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    67
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    68
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
    69
    private synchronized void waitOutputComplete() {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    70
        // Wait for stderr and stdout
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    71
        if (process != null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    72
            while (outputCompleteCount < 2) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    73
                try {wait();} catch (InterruptedException e) {}
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    74
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    75
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    76
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    77
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    78
    private Connector findConnector(String name) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    79
        for (Connector cntor :
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    80
                 Bootstrap.virtualMachineManager().allConnectors()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    81
            if (cntor.name().equals(name)) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    82
                return cntor;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    83
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    84
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    85
        return null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    86
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    87
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    88
    private Map <String, Connector.Argument> mergeConnectorArgs(Connector connector, Map<String, String> argumentName2Value) {
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    89
        Map<String, Connector.Argument> arguments = connector.defaultArguments();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    90
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    91
        for (Entry<String, String> argumentEntry : argumentName2Value.entrySet()) {
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    92
            String name = argumentEntry.getKey();
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    93
            String value = argumentEntry.getValue();
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
    94
            Connector.Argument argument = arguments.get(name);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    95
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    96
            if (argument == null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    97
                throw new IllegalArgumentException("Argument is not defined for connector:" +
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    98
                                          name + " -- " + connector.name());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    99
            }
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
   100
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   101
            argument.setValue(value);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   102
        }
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
   103
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   104
        return arguments;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   105
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   106
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   107
    /**
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   108
     * The JShell specific Connector args for the LaunchingConnector.
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   109
     *
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   110
     * @param portthe socket port for (non-JDI) commands
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   111
     * @param remoteVMOptions any user requested VM options
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   112
     * @return the argument map
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   113
     */
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   114
    private static Map<String, String> launchArgs(int port, String remoteVMOptions) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   115
        Map<String, String> argumentName2Value = new HashMap<>();
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   116
        argumentName2Value.put("main", REMOTE_AGENT + " " + port);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   117
        argumentName2Value.put("options", remoteVMOptions);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   118
        return argumentName2Value;
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   119
    }
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
   120
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   121
    /**
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   122
     * Start the remote agent and establish a JDI connection to it.
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   123
     *
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   124
     * @param ec the execution control instance
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   125
     * @param port the socket port for (non-JDI) commands
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   126
     * @param remoteVMOptions any user requested VM options
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   127
     * @param isLaunch does JDI do the launch? That is, LaunchingConnector,
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   128
     * otherwise we start explicitly and use ListeningConnector
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   129
     */
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   130
    JDIConnection(JDIExecutionControl ec, int port, List<String> remoteVMOptions, boolean isLaunch) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   131
        this(ec,
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   132
                isLaunch
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   133
                        ? "com.sun.jdi.CommandLineLaunch"
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   134
                        : "com.sun.jdi.SocketListen",
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   135
                isLaunch
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   136
                        ? launchArgs(port, String.join(" ", remoteVMOptions))
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   137
                        : new HashMap<>(),
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   138
                0);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   139
        if (isLaunch) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   140
            vm = launchTarget();
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   141
        } else {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   142
            vm = listenTarget(port, remoteVMOptions);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   143
        }
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   144
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   145
        if (isOpen() && vm().canBeModified()) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   146
            /*
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   147
             * Connection opened on startup.
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   148
             */
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   149
            new JDIEventHandler(vm(), (b) -> ec.handleVMExit())
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   150
                    .start();
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   151
        }
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   152
    }
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   153
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   154
    /**
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   155
     * Base constructor -- set-up a JDI connection.
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   156
     *
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   157
     * @param ec the execution control instance
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   158
     * @param connectorName the standardized name of the connector
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   159
     * @param argumentName2Value the argument map
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   160
     * @param traceFlags should we trace JDI behavior
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   161
     */
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
   162
    JDIConnection(JDIExecutionControl ec, String connectorName, Map<String, String> argumentName2Value, int traceFlags) {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
   163
        this.ec = ec;
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
   164
        this.connector = findConnector(connectorName);
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
   165
        if (connector == null) {
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
   166
            throw new IllegalArgumentException("No connector named: " + connectorName);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   167
        }
34755
135cde5b66cf 8143952: JShell: space in class path causes remote launch failure
jlahoda
parents: 33362
diff changeset
   168
        connectorArgs = mergeConnectorArgs(connector, argumentName2Value);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   169
        this.traceFlags = traceFlags;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   170
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   171
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   172
    final synchronized VirtualMachine vm() {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   173
        if (vm == null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   174
            throw new JDINotConnectedException();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   175
        } else {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   176
            return vm;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   177
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   178
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   179
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   180
    private synchronized boolean isOpen() {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   181
        return (vm != null);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   182
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   183
35002
209d72239196 8144906: Fix jshell's ToolBasicTest
jlahoda
parents: 34755
diff changeset
   184
    synchronized boolean isRunning() {
209d72239196 8144906: Fix jshell's ToolBasicTest
jlahoda
parents: 34755
diff changeset
   185
        return process != null && process.isAlive();
209d72239196 8144906: Fix jshell's ToolBasicTest
jlahoda
parents: 34755
diff changeset
   186
    }
209d72239196 8144906: Fix jshell's ToolBasicTest
jlahoda
parents: 34755
diff changeset
   187
38608
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   188
    // Beginning shutdown, ignore any random dying squeals
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   189
    void beginShutdown() {
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   190
        active = false;
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   191
    }
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   192
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   193
    synchronized void disposeVM() {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   194
        try {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   195
            if (vm != null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   196
                vm.dispose(); // This could NPE, so it is caught below
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   197
                vm = null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   198
            }
35002
209d72239196 8144906: Fix jshell's ToolBasicTest
jlahoda
parents: 34755
diff changeset
   199
        } catch (VMDisconnectedException ex) {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   200
            // Ignore if already closed
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   201
        } catch (Throwable e) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   202
            ec.debug(DBG_GEN, null, "disposeVM threw: " + e);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   203
        } finally {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   204
            if (process != null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   205
                process.destroy();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   206
                process = null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   207
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   208
            waitOutputComplete();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   209
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   210
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   211
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   212
    private void dumpStream(InputStream inStream, final PrintStream pStream) throws IOException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   213
        BufferedReader in =
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   214
            new BufferedReader(new InputStreamReader(inStream));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   215
        int i;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   216
        try {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   217
            while ((i = in.read()) != -1) {
38608
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   218
                // directly copy input to output, but skip if asked to close
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   219
                if (active) {
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   220
                    pStream.print((char) i);
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   221
                }
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   222
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   223
        } catch (IOException ex) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   224
            String s = ex.getMessage();
38608
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   225
            if (active && !s.startsWith("Bad file number")) {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   226
                throw ex;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   227
            }
38608
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   228
            // else we are being shutdown (and don't want any spurious death
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   229
            // throws to ripple) or
691b607bbcd6 8157917: JShell: shutdown could cause remote JDWP errors to be visible to users
rfield
parents: 38535
diff changeset
   230
            // we got a Bad file number IOException which just means
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   231
            // that the debuggee has gone away.  We'll just treat it the
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   232
            // same as if we got an EOF.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   233
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   234
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   235
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   236
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   237
     *  Create a Thread that will retrieve and display any output.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   238
     *  Needs to be high priority, else debugger may exit before
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   239
     *  it can be displayed.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   240
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   241
    private void displayRemoteOutput(final InputStream inStream, final PrintStream pStream) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   242
        Thread thr = new Thread("output reader") {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   243
            @Override
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   244
            public void run() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   245
                try {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   246
                    dumpStream(inStream, pStream);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   247
                } catch (IOException ex) {
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
   248
                    ec.debug(ex, "Failed reading output");
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   249
                    ec.handleVMExit();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   250
                } finally {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   251
                    notifyOutputComplete();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   252
                }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   253
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   254
        };
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   255
        thr.setPriority(Thread.MAX_PRIORITY-1);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   256
        thr.start();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   257
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   258
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   259
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   260
     *  Create a Thread that will ship all input to remote.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   261
     *  Does it need be high priority?
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   262
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   263
    private void readRemoteInput(final OutputStream outStream, final InputStream inputStream) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   264
        Thread thr = new Thread("input reader") {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   265
            @Override
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   266
            public void run() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   267
                try {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   268
                    byte[] buf = new byte[256];
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   269
                    int cnt;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   270
                    while ((cnt = inputStream.read(buf)) != -1) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   271
                        outStream.write(buf, 0, cnt);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   272
                        outStream.flush();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   273
                    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   274
                } catch (IOException ex) {
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 35002
diff changeset
   275
                    ec.debug(ex, "Failed reading output");
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   276
                    ec.handleVMExit();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   277
                }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   278
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   279
        };
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   280
        thr.setPriority(Thread.MAX_PRIORITY-1);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   281
        thr.start();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   282
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   283
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   284
    private void forwardIO() {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   285
        displayRemoteOutput(process.getErrorStream(), ec.execEnv.userErr());
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   286
        displayRemoteOutput(process.getInputStream(), ec.execEnv.userOut());
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   287
        readRemoteInput(process.getOutputStream(), ec.execEnv.userIn());
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   288
    }
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   289
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   290
    /* launch child target vm */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   291
    private VirtualMachine launchTarget() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   292
        LaunchingConnector launcher = (LaunchingConnector)connector;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   293
        try {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   294
            VirtualMachine new_vm = launcher.launch(connectorArgs);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   295
            process = new_vm.process();
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   296
            forwardIO();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   297
            return new_vm;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   298
        } catch (Exception ex) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   299
            reportLaunchFail(ex, "launch");
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   300
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   301
        return null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   302
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   303
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   304
    /**
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   305
     * Directly launch the remote agent and connect JDI to it with a
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   306
     * ListeningConnector.
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   307
     */
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   308
    private VirtualMachine listenTarget(int port, List<String> remoteVMOptions) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   309
        ListeningConnector listener = (ListeningConnector) connector;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   310
        try {
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   311
            // Start listening, get the JDI connection address
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   312
            String addr = listener.startListening(connectorArgs);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   313
            ec.debug(DBG_GEN, "Listening at address: " + addr);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   314
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   315
            // Launch the RemoteAgent requesting a connection on that address
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   316
            String javaHome = System.getProperty("java.home");
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   317
            List<String> args = new ArrayList<>();
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   318
            args.add(javaHome == null
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   319
                    ? "java"
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   320
                    : javaHome + File.separator + "bin" + File.separator + "java");
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   321
            args.add("-agentlib:jdwp=transport=" + connector.transport().name() +
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   322
                    ",address=" + addr);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   323
            args.addAll(remoteVMOptions);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   324
            args.add(REMOTE_AGENT);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   325
            args.add("" + port);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   326
            ProcessBuilder pb = new ProcessBuilder(args);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   327
            process = pb.start();
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   328
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   329
            // Forward out, err, and in
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   330
            forwardIO();
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   331
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   332
            // Accept the connection from the remote agent
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   333
            vm = listener.accept(connectorArgs);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   334
            listener.stopListening(connectorArgs);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   335
            return vm;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   336
        } catch (Exception ex) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   337
            reportLaunchFail(ex, "listen");
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   338
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   339
        return null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   340
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   341
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   342
    private void reportLaunchFail(Exception ex, String context) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   343
        throw new InternalError("Failed remote " + context + ": " + connector +
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   344
                " -- " + connectorArgs, ex);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   345
    }
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38608
diff changeset
   346
}