Reputation: 415
I'm trying to execute task with Runtime.getRuntime().exec
.
I am getting "task started" in console. And the task gets executed and was completed.
Never got "task completed" printed.
Do you know what could be the reason? or How can I handle?
System.out.println("task started");
Process process = Runtime.getRuntime().exec("cmd.exe /c task.bat task.job");
process.waitFor();
System.out.println("task completed");
Why is process.waitFor()
not returning?
Upvotes: 0
Views: 1177
Reputation: 5862
According to the JavaDoc of class Process
some platforms have a limited buffer for the output:
All its standard I/O (i.e. stdin, stdout, stderr) operations [..] can be accessed via [..]
getOutputStream()
,getInputStream()
, andgetErrorStream()
. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
Try the following, before you call process.waitFor()
:
getErrorStream()
and getOutputStream()
andUpvotes: 1
Reputation: 1084
The problem might be that you should read all output (standard and error, so that process could quit)
So, you probably need to do this
final ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "task.bat", "task.job");
// if you want process output to be printed by you program
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
// if you don't want to show anything
// processBuilder.redirectError(ProcessBuilder.Redirect.DISCARD);
// processBuilder.redirectOutput(ProcessBuilder.Redirect.DISCARD);
Process process = processBuilder.start();
int exitCode = process.waitFor();
System.out.println(exitCode);
Upvotes: 1
Reputation: 9377
The exec
command is returning a process-handle (like the PID).
If the process has already terminated, you can query its exit-value with
process.exitValue()
as int
:
By convention, the value
0
indicates normal termination.
otherwise if the process is still running:
IllegalThreadStateException
- if the subprocess represented by this Process object has not yet terminated
Same for waitFor()
:
This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
Since the blocking is not what you probably want, can set a timeout here, then return of waitFor(long, TimeUnit)
changes.
So you can wrap in a try-catch block to get complete control:
Process process = null;
System.out.println("Task will start soon ..");
try {
process = Runtime.getRuntime().exec("cmd.exe /c task.bat task.job");
System.out.println("Task started.");
boolean alreadyTerminated = process.waitFor(50L, TimeUnit.SECONDS); // you can also set a timeout
if (!alreadyTerminated)
System.out.println("Task still executing. Will wait for 50 seconds.");
int exitValue = process.exitValue();
System.out.println("Task completed with exit-code: " + exitValue);
} catch (IllegalThreadStateException e) {
System.out.println(e);
}
Upvotes: 0