in com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java [64:172]
public CompletableFuture<Response> launchInTerminal(LaunchArguments launchArguments, Response response, IDebugAdapterContext context) {
CompletableFuture<Response> resultFuture = new CompletableFuture<>();
IVirtualMachineManagerProvider vmProvider = context.getProvider(IVirtualMachineManagerProvider.class);
vmHandler.setVmProvider(vmProvider);
final String launchInTerminalErrorFormat = "Failed to launch debuggee in terminal. Reason: %s";
try {
List<ListeningConnector> connectors = vmProvider.getVirtualMachineManager().listeningConnectors();
ListeningConnector listenConnector = connectors.get(0);
Map<String, Connector.Argument> args = listenConnector.defaultArguments();
((Connector.IntegerArgument) args.get("timeout")).setValue(ATTACH_TERMINAL_TIMEOUT);
String address = listenConnector.startListening(args);
String[] cmds = LaunchRequestHandler.constructLaunchCommands(launchArguments, false, address);
RunInTerminalRequestArguments requestArgs = null;
if (launchArguments.console == CONSOLE.integratedTerminal) {
requestArgs = RunInTerminalRequestArguments.createIntegratedTerminal(
cmds,
launchArguments.cwd,
launchArguments.env,
TERMINAL_TITLE);
} else {
requestArgs = RunInTerminalRequestArguments.createExternalTerminal(
cmds,
launchArguments.cwd,
launchArguments.env,
TERMINAL_TITLE);
}
Request request = new Request(Command.RUNINTERMINAL.getName(),
(JsonObject) JsonUtils.toJsonTree(requestArgs, RunInTerminalRequestArguments.class));
// Notes: In windows (reference to https://support.microsoft.com/en-us/help/830473/command-prompt-cmd--exe-command-line-string-limitation),
// when launching the program in cmd.exe, if the command line length exceed the threshold value (8191 characters),
// it will be automatically truncated so that launching in terminal failed. Especially, for maven project, the class path contains
// the local .m2 repository path, it may exceed the limit.
context.getProtocolServer().sendRequest(request, RUNINTERMINAL_TIMEOUT)
.whenComplete((runResponse, ex) -> {
if (runResponse != null) {
if (runResponse.success) {
try {
VirtualMachine vm = listenConnector.accept(args);
vmHandler.connectVirtualMachine(vm);
context.setDebugSession(new DebugSession(vm));
logger.info("Launching debuggee in terminal console succeeded.");
resultFuture.complete(response);
} catch (TransportTimeoutException e) {
int commandLength = StringUtils.length(launchArguments.cwd) + 1;
for (String cmd : cmds) {
commandLength += StringUtils.length(cmd) + 1;
}
final int threshold = SystemUtils.IS_OS_WINDOWS ? 8092 : 32 * 1024;
String errorMessage = String.format(launchInTerminalErrorFormat, e.toString());
if (commandLength >= threshold) {
errorMessage = "Failed to launch debuggee in terminal. The possible reason is the command line too long. "
+ "More details: " + e.toString();
logger.severe(errorMessage
+ "\r\n"
+ "The estimated command line length is " + commandLength + ". "
+ "Try to enable shortenCommandLine option in the debug launch configuration.");
}
resultFuture.completeExceptionally(
new DebugException(
errorMessage,
ErrorCode.LAUNCH_IN_TERMINAL_FAILURE.getId()
)
);
} catch (IOException | IllegalConnectorArgumentsException e) {
resultFuture.completeExceptionally(
new DebugException(
String.format(launchInTerminalErrorFormat, e.toString()),
ErrorCode.LAUNCH_IN_TERMINAL_FAILURE.getId()
)
);
}
} else {
resultFuture.completeExceptionally(
new DebugException(
String.format(launchInTerminalErrorFormat, runResponse.message),
ErrorCode.LAUNCH_IN_TERMINAL_FAILURE.getId()
)
);
}
} else {
if (ex instanceof CompletionException && ex.getCause() != null) {
ex = ex.getCause();
}
String errorMessage = String.format(launchInTerminalErrorFormat, ex != null ? ex.toString() : "Null response");
resultFuture.completeExceptionally(
new DebugException(
String.format(launchInTerminalErrorFormat, errorMessage),
ErrorCode.LAUNCH_IN_TERMINAL_FAILURE.getId()
)
);
}
});
} catch (IOException | IllegalConnectorArgumentsException e) {
resultFuture.completeExceptionally(
new DebugException(
String.format(launchInTerminalErrorFormat, e.toString()),
ErrorCode.LAUNCH_IN_TERMINAL_FAILURE.getId()
)
);
}
return resultFuture;
}