brettwooldridge / NuProcess

Low-overhead, non-blocking I/O, external Process implementation for Java
Apache License 2.0
712 stars 84 forks source link

(Question) Detecting process creation failure #66

Closed bturner closed 7 years ago

bturner commented 7 years ago

The various NuProcessFactory implementations all seem to follow a similar approach:

XyzProcess process = new XyzProcess(processListener);
process.start(...);
return process;

process.start(...), for all types, returns a NuProcess (specifically, all the implementations return this;, but it can also return null; if the process isn't started), but that value is never considered. So the factory implementations never return null.

Since the factory is returning the instantiated object, though, how is one to detect that the process couldn't be started? I can check isRunning(), but that doesn't help me differentiate between a fast-exiting process and a process that failed to start, since all of the start() implementations print stack traces rather than propagating exceptions. It looks like I could differentiate between failed start and fast exit by checking whether onStart was ever invoked on my NuProcessHandler. Is that how you'd recommend checking? isRunning() set to false and onStart never invoked?

Is there any possibility that NuProcess could be changed to provide a better mechanism for detecting processes that can't be started? The most obvious approach would be to have NuProcessBuilder.start() throw an exception, but that seems to be against the design ethos for the project.

brettwooldridge commented 7 years ago

@bturner If a process fails to start:

I'm not sure there is a "recommended" way of handling failures, but probably the one likely to provide the most detail about the failure is to rely on onExit() being called.

class ProcessHandler extends NuAbstractProcessHandler {
   private NuProcess nuProcess;

   public void onStart(NuProcess nuProcess) {
      this.nuProcess = nuProcess;
   }

   public void onExit(int exitCode) {
      if (nuProcess == null) {
          // Launch failure.  exitCode may or may not be useful.
      }
      else {
         // normal exit handling
      }
   }
   ...
}