When Runtime.exec() won't - JavaWorld
When Runtime.exec() won't
Navigate yourself around pitfalls related to the Runtime.exec() method
By Michael C. Daconta, JavaWorld.com, 12/29/00
As part of the Java language, thejava.langpackage is implicitly imported into every Java program. This package's pitfalls surface often, affecting most programmers. This month, I'll discuss the traps lurking in theRuntime.exec()method.
Pitfall 4: When Runtime.exec() won't
The class
java.lang.Runtimefeatures a static method calledgetRuntime(), which retrieves the current Java Runtime Environment. That is the only way to obtain a reference to theRuntimeobject. With that reference, you can run external programs by invoking theRuntimeclass'sexec()method. Developers often call this method to launch a browser for displaying a help page in HTML.There are four overloaded versions of the
exec()command:
public Process exec(String command);public Process exec(String [] cmdArray);public Process exec(String command, String [] envp);public Process exec(String [] cmdArray, String [] envp);
For each of these methods, a command -- and possibly a set of arguments -- is passed to an operating-system-specific function call. This subsequently creates an operating-system-specific process (a running program) with a reference to a
Processclass returned to the Java VM. TheProcessclass is an abstract class, because a specific subclass ofProcessexists for each operating system.You can pass three possible input parameters into these methods:
- A single string that represents both the program to execute and any arguments to that program
- An array of strings that separate the program from its arguments
- An array of environment variables
Pass in the environment variables in the form
name=value. If you use the version ofexec()with a single string for both the program and its arguments, note that the string is parsed using white space as the delimiter via theStringTokenizerclass.Stumbling into an IllegalThreadStateException
The first pitfall relating to
Runtime.exec()is theIllegalThreadStateException. The prevalent first test of an API is to code its most obvious methods. For example, to execute a process that is external to the Java VM, we use theexec()method. To see the value that the external process returns, we use theexitValue()method on theProcessclass. In our first example, we will attempt to execute the Java compiler (javac.exe):Listing 4.1 BadExecJavac.java
import java.util.*; import java.io.*; public class BadExecJavac { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("javac"); int exitVal = proc.exitValue(); System.out.println("Process exitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } }
A run of
BadExecJavacproduces:E:\classes\com\javaworld\jpitfalls\article2>java BadExecJavac java.lang.IllegalThreadStateException: process has not exited at java.lang.Win32Process.exitValue(Native Method) at BadExecJavac.main(BadExecJavac.java:13)
If an external process has not yet completed, the
exitValue()method will throw anIllegalThreadStateException; that's why this program failed. While the documentation states this fact, why can't this method wait until it can give a valid answer?
I finally found the answer that bugged me the whole afternoon.... Hope it'll solve my bug after I try it out tomorrow...