public void launch(Monitored mp) {
    if (!lifecycle.tryToMoveTo(Lifecycle.State.STARTING)) {
      throw new IllegalStateException("Already started");
    }
    monitored = mp;

    Logger logger = LoggerFactory.getLogger(getClass());
    try {
      launch(logger);
    } catch (Exception e) {
      logger.warn("Fail to start {}", processId.getHumanReadableName(), e);
      hardStop();
    }
  }
@Test
  public void terminate_if_unexpected_shutdown() throws Exception {
    Props props = createProps();
    final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, commands, runtime);
    final StandardProcess process = new StandardProcess();

    Thread runner = new Thread(() -> {
      // starts and waits until terminated
      entryPoint.launch(process);
    });
    runner.start();

    waitForOperational(process, commands);

    // emulate signal to shutdown process
    ArgumentCaptor<Thread> shutdownHookCaptor = ArgumentCaptor.forClass(Thread.class);
    verify(runtime).addShutdownHook(shutdownHookCaptor.capture());
    shutdownHookCaptor.getValue().start();

    while (process.getState() != State.STOPPED) {
      Thread.sleep(10L);
    }
    // exit before test timeout, ok !
  }