Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

When Runtime.exec() won't

Navigate yourself around pitfalls related to the Runtime.exec() method

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

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?

Why Runtime.exec() hangs

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).

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (45)
Login
Forgot your account info?

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

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources