ProcessListener (@NotNull final Pair<Target, Parameters> key) { return new ProcessListener() { @Override public void startNotified(@NotNull ProcessEvent event) { ProcessHandler processHandler = event.getProcessHandler(); processHandler.putUserData(ProcessHandler.SILENTLY_DESTROY_ON_CLOSE, Boolean.TRUE); Info o; synchronized (myProcMap) { o = myProcMap.get(key); if (o instanceof PendingInfo) { myProcMap.put(key, new PendingInfo(((PendingInfo)o).ref, processHandler)); } } sendDataAfterStart(processHandler); } @Override public void processTerminated(@NotNull ProcessEvent event) { if (dropProcessInfo(key, null, event.getProcessHandler())) { fireModificationCountChanged(); } onProcessTerminated(event); } @Override public void processWillTerminate(@NotNull ProcessEvent event, boolean willBeDestroyed) { if (dropProcessInfo(key, null, event.getProcessHandler())) { fireModificationCountChanged(); } Heartbeat heartbeat = myHeartbeatRef.get(); if (heartbeat != null) { heartbeat.stopBeat(); } } @Override public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { String text = StringUtil.notNullize(event.getText()); logText(key.second, event, outputType); RunningInfo result = null; PendingInfo info; synchronized (myProcMap) { Info o = myProcMap.get(key); if (o instanceof PendingInfo) { info = (PendingInfo)o; if (outputType == ProcessOutputTypes.STDOUT) { String prefix = "Port/ServicesPort/ID:"; if (text.startsWith(prefix)) { List<String> data = StringUtil.split(text.substring(prefix.length()).trim(), "/"); int port = Integer.parseInt(data.get(0)); int servicesPort = Integer.parseInt(data.get(1)); String id = data.get(2); result = new RunningInfo(info.handler, getRemoteHost(), publishPort(port), id, publishPort(servicesPort)); myProcMap.put(key, result); myProcMap.notifyAll(); } } else if (outputType == ProcessOutputTypes.STDERR) { info.stderr.append(text); } } else { info = null; } } if (result != null) { synchronized (info.ref) { info.ref.set(result); info.ref.notifyAll(); } fireModificationCountChanged(); try { Heartbeat heartbeat = new Heartbeat(result.host, result.port); heartbeat.startBeat(); myHeartbeatRef.set(heartbeat); } catch (Throwable e) { LOG.warn("The cook failed to start due to " + ExceptionUtil.getRootCause(e)); } } } }; }