Page 2 of 4
A more thorough look at the methods available in the Process class reveals a waitFor() method that does precisely that. In fact, waitFor() also returns the exit value, which means that you would not use exitValue() and waitFor() in conjunction with each other, but rather would choose one or the other. The only possible time you would use exitValue() instead of waitFor() would be when you don't want your program to block waiting on an external process that may never complete. Instead of using
the waitFor() method, I would prefer passing a boolean parameter called waitFor into the exitValue() method to determine whether or not the current thread should wait. A boolean would be more beneficial because exitValue() is a more appropriate name for this method, and it isn't necessary for two methods to perform the same function under different
conditions. Such simple condition discrimination is the domain of an input parameter.
Therefore, to avoid this trap, either catch the IllegalThreadStateException or wait for the process to complete.
Now, let's fix the problem in Listing 4.1 and wait for the process to complete. In Listing 4.2, the program again attempts
to execute javac.exe and then waits for the external process to complete:
Listing 4.2 BadExecJavac2.java
import java.util.*;
import java.io.*;
public class BadExecJavac2
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("javac");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (Throwable t)
{
t.printStackTrace();
}
}
}
Unfortunately, a run of BadExecJavac2 produces no output. The program hangs and never completes. Why does the javac process never complete?
The JDK's Javadoc documentation provides the answer to this question:
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, and even deadlock.
Is this just a case of programmers not reading the documentation, as implied in the oft-quoted advice: read the fine manual (RTFM)? The answer is partially yes. In this case, reading the Javadoc would get you halfway there; it explains that you need to handle the streams to your external process, but it does not tell you how.
Another variable is at play here, as is evident by the large number of programmer questions and misconceptions concerning
this API in the newsgroups: though Runtime.exec() and the Process APIs seem extremely simple, that simplicity is deceiving because the simple, or obvious, use of the API is
prone to error. The lesson here for the API designer is to reserve simple APIs for simple operations. Operations prone to
complexities and platform-specific dependencies should reflect the domain accurately. It is possible for an abstraction to
be carried too far. The JConfig library provides an example of a more complete API to handle file and process operations (see Resources below for more information).
JConfig library or download it for evaluation
This artcle is very good. Thnaks for your helpBy Anonymous on February 9, 2010, 8:59 amThis artcle is very good. Thnaks for your help
Reply | Read entire comment
Nice article, it resolved my 'rar.exe' deaklock problemBy Anonymous on January 27, 2010, 6:50 amI write waitFor() BEFORE consuming StdOut/StdErr stream of the process, so the 'rar.exe LARGE_FILE' process is deadlock. Moved waitFor() AFTER consuming StdOut/StdErr...
Reply | Read entire comment
hai i need to execte the command "javac" by using this how can iBy Anonymous on January 17, 2010, 1:50 pmhai i need to execte the command "javac" by using this how can i do this
Reply | Read entire comment
Thank you for the great article! But something is missing, how dBy Anonymous on December 20, 2009, 5:15 amThank you for the great article! But something is missing, how do I properly send commands to an already runnnig process? Of course I have tried the process.getOutputStream(),...
Reply | Read entire comment
Application exit value 128By Anonymous on December 18, 2009, 8:43 amHello, i use the Runtime exec with the Class "StreamGobbler" to execute one of my application (exe) and the exit value of the watFor is 128. There is no such return...
Reply | Read entire comment
View all comments