public void execute() throws Exception {
        interruptWatcherThread.setDaemon(true);
        interruptWatcherThread.start();

        LOG.info("about to start driver");
        start();
        while (!userInterrupted) {
            Integer exit = null;
            try {
                LOG.trace("about to check exit value");
                exit = process.exitValue();
                LOG.info("The forked process has finished with an exit value of: {}", exit);
                stop();
            } catch (IllegalThreadStateException e) {
                //hasn't exited
                LOG.trace("process has not exited; IllegalThreadStateException");
            }

            LOG.trace("Before sleep: exit={} receivedRestartMsg={}", exit, receivedRestartMsg);

            //Even if the process has exited,
            //wait just a little bit to make sure that
            //mustRestart hasn't been set to true
            try {
                Thread.sleep(pulseMillis);
            } catch (InterruptedException e) {
                LOG.trace("interrupted exception during sleep");
            }
            LOG.trace("After sleep: exit={} receivedRestartMsg={}", exit, receivedRestartMsg);
            //if we've gotten the message via stdout to restart
            //but the process hasn't exited yet, give it another
            //chance
            if (receivedRestartMsg && exit == null && loopsAfterRestartMessageReceived <= waitNumLoopsAfterRestartMessage) {
                loopsAfterRestartMessageReceived++;
                LOG.warn("Must restart, still not exited; loops after restart: {}", loopsAfterRestartMessageReceived);
                continue;
            }
            if (loopsAfterRestartMessageReceived > waitNumLoopsAfterRestartMessage) {
                LOG.trace("About to try to restart because: exit={} receivedRestartMsg={}", exit, receivedRestartMsg);
                LOG.warn("Restarting after exceeded wait loops waiting for exit: {}", loopsAfterRestartMessageReceived);
                boolean restarted = restart(exit, receivedRestartMsg);
                if (!restarted) {
                    break;
                }
            } else if (exit != null && exit != BatchProcessDriverCLI.PROCESS_NO_RESTART_EXIT_CODE && exit != BatchProcessDriverCLI.PROCESS_COMPLETED_SUCCESSFULLY) {
                LOG.trace("About to try to restart because: exit={} receivedRestartMsg={}", exit, receivedRestartMsg);

                if (exit == BatchProcessDriverCLI.PROCESS_RESTART_EXIT_CODE) {
                    LOG.info("Restarting on expected restart code");
                } else {
                    LOG.warn("Restarting on unexpected restart code: {}", exit);
                }
                boolean restarted = restart(exit, receivedRestartMsg);
                if (!restarted) {
                    break;
                }
            } else if (exit != null && (exit == PROCESS_COMPLETED_SUCCESSFULLY || exit == BatchProcessDriverCLI.PROCESS_NO_RESTART_EXIT_CODE)) {
                LOG.trace("Will not restart: {}", exit);
                break;
            }
        }

        LOG.trace("about to call shutdown driver now");
        shutdownDriverNow();
        LOG.info("Process driver has completed");
    }
This relies on an special exit values of 254 (do not restart),
0 ended correctly, 253 ended with exception (do restart)
tika-batch/src/main/java/org/apache/tika/batch/BatchProcessDriverCLI.java