Process Builder and Process in Java - how to run a process with a timeout :?

I need to execute an external batch file in java with a specific timeout. this means that if the batch takes longer than the specified timeout, I need to cancel the execution.

here is an example of the code i wrote:

public static void main(String[] args) throws IOException, InterruptedException { ProcessBuilder p = new ProcessBuilder("c:\\wait.bat", "25"); // batch file execution will take 25 seconds. final long l = System.currentTimeMillis(); System.out.println("starting..." + (System.currentTimeMillis() - l)); final Process command = p.start(); System.out.println("started..." + (System.currentTimeMillis() - l)); Timer t = new Timer(); t.schedule(new TimerTask() { @Override public void run() { command.destroy(); } }, 5000); // it will kill the process after 5 seconds (if it not finished yet). int i = command.waitFor(); t.cancel(); System.out.println("done..." + (System.currentTimeMillis() - l)); System.out.println("result : " + i); System.out.println("Really Done..." + (System.currentTimeMillis() - l)); } 

The wait.bat batch file looks something like this:

 @echo off echo starting the process... @ping 127.0.0.1 -n 2 -w 1000 > nul @ping 127.0.0.1 -n %1% -w 1000> nul echo process finished succesfully @echo on 

As you can see in the code, the batch file will take 25 seconds (the first line in the main method), and the timer will destroy the command in 5 seconds.

here is the output of my code:

 starting...0 started...0 done...5000 result : 1 Really Done...5000 BUILD SUCCESSFUL (total time: 25 seconds) 

as you can see in the output, the last line ("Really Done ...") is executed at the 5th second, but the application terminates after 25 seconds.

my question is: although I called the destroy method in my timer, why is jvm still waiting for the process to complete?

+5
java process
Feb 28 '11 at 6:39
source share
3 answers

This is a bug in the implementation of Java Process.destroy() on Windows. The problem is that the batch script (or its executing shell) is killed, but does not kill its own child processes (ping here). Thus, ping still works after .destroy() , as well as after .waitFor() . But for some reason, the VM is still waiting for ping to complete before ending itself.

There seems to be nothing you can do here on the Java side to really kill ping.

You might consider using start (in your script package or externally) to invoke your ping as a separate process.

(See also the previous discussion .)

Or switch to a unix-like operating system.

+8
Feb 28 2018-11-28T00:
source share
— -

If you are using Unix / Linux, write a bash shell script to abort an external command with a timeout, then call the shell from Java.

The shell script looks like

 #!/bin/bash timeout 60 <your command> 

You can determine if the timeout has passed by checking the script exit code, which is 124 in the case of a timeout

Cm.

user timeout

+1
03 Mar. '14 at 16:25
source share

I might be having a problem with the timer cancel method. try starting the timer as a daemon thread.

 Timer t = new Timer(true); 
0
Feb 28 '11 at 7:17
source share



All Articles