Class ProcessUtils

java.lang.Object
org.apache.tika.utils.ProcessUtils

public class ProcessUtils extends Object
  • Field Details

    • HEARTBEAT_INTERVAL_MILLIS

      public static final long HEARTBEAT_INTERVAL_MILLIS
      See Also:
    • DEFAULT_CHECK_COMMAND_TIMEOUT_MILLIS

      public static final long DEFAULT_CHECK_COMMAND_TIMEOUT_MILLIS
      See Also:
  • Constructor Details

    • ProcessUtils

      public ProcessUtils()
  • Method Details

    • escapeCommandLine

      public static String escapeCommandLine(String arg)
      This should correctly put double-quotes around an argument if ProcessBuilder doesn't seem to work (as it doesn't on paths with spaces on Windows)
      Parameters:
      arg -
      Returns:
    • unescapeCommandLine

      public static String unescapeCommandLine(String arg)
    • execute

      public static FileProcessResult execute(ProcessBuilder pb, long requestedTimeoutMillis, int maxStdoutBuffer, int maxStdErrBuffer) throws IOException
      This writes stdout and stderr to the FileProcessResult.

      Equivalent to execute(ProcessBuilder, ParseContext, long, int, int) with a null context: requestedTimeoutMillis is granted unclipped, no checkpointing.

      Parameters:
      pb -
      requestedTimeoutMillis -
      maxStdoutBuffer -
      maxStdErrBuffer -
      Returns:
      Throws:
      IOException
    • execute

      public static FileProcessResult execute(ProcessBuilder pb, ParseContext context, long requestedTimeoutMillis, int maxStdoutBuffer, int maxStdErrBuffer) throws IOException
      Same as execute(ProcessBuilder, long, int, int), but bounds the wait to min(requestedTimeoutMillis, ParseTimeout.remainingMillis()) (see ParseTimeout.budgetFor(long)) so no single call can outlast the task's total timeout regardless of its own configuration. The granted budget and original request are both recorded on the result (see FileProcessResult.getRequestedTimeoutMillis(), FileProcessResult.isClippedByRemaining()).

      While waiting, checkpoints the ParseTimeout in context (if any) every 1000L ms, so a bounded external call can run longer than the progress (stall-detection) timeout without looking like a hang -- the wait itself is progress. A null context behaves like the four-argument overload.

      Parameters:
      pb -
      context - may be null
      requestedTimeoutMillis - the timeout the caller's own configuration asks for
      maxStdoutBuffer -
      maxStdErrBuffer -
      Returns:
      Throws:
      IOException
    • execute

      public static FileProcessResult execute(ProcessBuilder pb, long requestedTimeoutMillis, Path stdoutRedirect, int maxStdErrBuffer) throws IOException
      This redirects stdout to stdoutRedirect path.

      Equivalent to execute(ProcessBuilder, ParseContext, long, Path, int) with a null context, i.e. requestedTimeoutMillis is granted unclipped and the wait does not checkpoint any task's progress timeout.

      Parameters:
      pb -
      requestedTimeoutMillis -
      stdoutRedirect -
      maxStdErrBuffer -
      Returns:
      Throws:
      IOException
    • execute

      public static FileProcessResult execute(ProcessBuilder pb, ParseContext context, long requestedTimeoutMillis, Path stdoutRedirect, int maxStdErrBuffer) throws IOException
      Same as execute(ProcessBuilder, long, Path, int), but bounds the wait to min(requestedTimeoutMillis, ParseTimeout.remainingMillis()) and checkpoints while waiting -- see execute(ProcessBuilder, ParseContext, long, int, int).
      Parameters:
      pb -
      context - may be null
      requestedTimeoutMillis - the timeout the caller's own configuration asks for
      stdoutRedirect -
      maxStdErrBuffer -
      Returns:
      Throws:
      IOException
    • checkCommand

      public static boolean checkCommand(String checkCmd, int... errorValue)
      Checks to see if the command can be run. Typically used with something like "myapp --version" to check to see if "myapp" is installed and on the path.

      Equivalent to checkCommandWithTimeout(String[], long, int...) with DEFAULT_CHECK_COMMAND_TIMEOUT_MILLIS.

      Parameters:
      checkCmd - The check command to run
      errorValue - What is considered an error value? Default is 127 (command not found).
      Returns:
      true if the command ran successfully (exit code not in errorValue list)
    • checkCommand

      public static boolean checkCommand(String[] checkCmd, int... errorValue)
      Checks to see if the command can be run. Typically used with something like new String[]{"myapp", "--version"} to check to see if "myapp" is installed and on the path.

      Equivalent to checkCommandWithTimeout(String[], long, int...) with DEFAULT_CHECK_COMMAND_TIMEOUT_MILLIS.

      Parameters:
      checkCmd - The check command to run
      errorValue - What is considered an error value? Default is 127 (command not found).
      Returns:
      true if the command ran successfully (exit code not in errorValue list)
    • checkCommandWithTimeout

      public static boolean checkCommandWithTimeout(String[] checkCmd, long timeoutMillis, int... errorValue)
      Same as checkCommand(String[], int...), but with a caller-specified timeout instead of the 5000Lms default.

      Deliberately a distinct method name, not a same-named overload: checkCommand(cmd, 500) would silently resolve to checkCommand(String[], int...) with errorValue={500} at the default timeout -- Java prefers the varargs-only overload over widening int to this method's long parameter, with no compile error to catch the mistake.

      Parameters:
      timeoutMillis - how long to wait for the command to exit
      errorValue - What is considered an error value? Default is 127 (command not found).
      Returns:
      true if the command ran successfully (exit code not in errorValue list)
    • waitForWithHeartbeat

      public static boolean waitForWithHeartbeat(Process p, ParseContext context, long timeoutMillis) throws InterruptedException
      Waits for the process to exit, like Process.waitFor(long, TimeUnit), but polls in 1000L ms increments and checkpoints context's ParseTimeout after each increment that doesn't complete -- this is what lets a bounded external call run longer than the progress timeout without tripping the stall detector: the wait itself is progress.

      Public so callers managing their own Process (not going through execute(ProcessBuilder, ParseContext, long, int, int)) can still checkpoint while waiting.

      Parameters:
      context - may be null, in which case no checkpoint is recorded
      timeoutMillis - total wait time in ms; zero or negative checks once without waiting
      Returns:
      true if the process exited before the timeout elapsed
      Throws:
      InterruptedException