简体   繁体   中英

Java process.waitFor(time, unit) does not time out

In my Java 11 (openjdk 11.0.3 2019-04-16 under Debian) program I use ProcessBuilder to launch external commands. The external command can hang so I need it to time out after a given amount of time.

So I use p.waitFor(time, unit) which should return

true if the process has exited and false if the waiting time elapsed before the process has exited.

        ProcessBuilder pb = new ProcessBuilder(externalCommand);

        // Merges the error stream with the standard output stream
        pb.redirectErrorStream(true);

        Process p = pb.start();

        Date start = new Date();

        BufferedReader br = new BufferedReader(new InputStreamReader(
                p.getInputStream()));

        String tempLine;

        /**
         * We only want the first 10 lines otherwise it will print thousands of
         * useless lines (always the same)
         */
        int nbOfLinesInlogs = 10;

        while ((tempLine = br.readLine()) != null) {

            // We only report errors to the user
            if (tempLine.toLowerCase().startsWith("error") && nbOfLinesInlogs > 0) {
                Level level = Level.WARNING;


                System.err.println("External command output : " + tempLine);
                // There was an error
                errorDetected = true;

                nbOfLinesInlogs--;
            }

        }


        if (p.waitFor(10l,
                TimeUnit.NANOSECONDS)) {

            long elapsedInMillis = new Date().getTime() - start.getTime();
            System.err.println("External process succeeded and took " + elapsedInMillis + " ms");
            // prints Externalprocess succeeded and took 15327 ms
            ...
         }
         else {
            System.err.println("External process timed out");
            // This is never printed!
            throw new InterruptedException(
                    "External process timed out!");
         } 

However the process never times out and prints that it took 15 s although it should time out after 10 ns (this is just a test to check that the time out works as expected). I also tried µs, ms and s with the same result.

What can I do to make the process return false when it times out ?

Any help appreciated,

Thanks all for your comments. According to the comments above, one solution is to remove the piece of code between the process start and the process wait process ( waitFor(...) )

p = pb.start()
// Everything in-between removed
if(p.waitFor(10l, TimeUnit.MILLISECONDS)) {

// Now this code is not processed in case of time out
}

The reason is (see @TreffnonX comment)

Because I used a while loop which only returns false, once the input is closed. Since my input only closes when the process terminates, my check (waitFor) happens after the process has ended.

Another solution could be to launch a separate thread that will run this while loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM