Name: krT82822 Date: 04/07/99
In order to workaround the bug in Proces.waitfor which hangs if there
is too much output to the pipe (Bug fix promised but not delivered in JDK 1.2)
I have been relying on the Process.exitValue() to indicate when the process
has completed. If you call this method on a process that is still running
it is supposed to throw IllegalThreadStateException. It doesn't always do
this. Here's some code to illustrate the bug.
package bugs.example;
import java.io.*;
import java.util.*;
public class SimpleProcess_Tester {
public SimpleProcess_Tester() {
runTest();
}
public static void main(String[] args) {
SimpleProcess_Tester simpleProcess_Tester = new SimpleProcess_Tester();
simpleProcess_Tester.invokedStandalone = true;
}
private boolean invokedStandalone = false;
private void runTest(){
for(int i=0;i<10;i++)
try{
String commandString="command.com /c \\\\julia\\main\\jbuilder3\\java\\bin\\javac";
String StdError="";
String StdOut="";
Process p = Runtime.getRuntime().exec(commandString, null);
InputStream dis = p.getInputStream();
InputStream err= p.getErrorStream();
int c;
//This next little diddy is a workaround to get the output on StdOut.
//You cannot use process.waitFor() because it hangs. The pipe fills up and the whole thing craps out.
//It's annoying but there is a fix promised from Sun, although yet to be delivered.
boolean processRunning=true;
while(processRunning){
Thread.sleep(500);
try{
while(dis.available()>0 && (c = dis.read()) != -1)
StdOut+=(char)c;
while(err.available()>0 && (c = err.read()) != -1)
StdError+=(char)c;
int exitVal=p.exitValue();
//If we get this far without an exception the process has finished
processRunning=false;
//Now suck up any extra characters that might have been generated by
//the thread before our call to p.exitValue()
try{
while(dis.available()>0 && (c = dis.read()) != -1)
StdOut+=(char)c;
}catch(Exception exc){
}
try{
while(err.available()>0 && (c = err.read()) != -1)
StdError+=(char)c;
}catch(Exception exc){
}
}catch (IllegalThreadStateException exc) {
Thread.yield();
Thread.sleep(100);
}
}
int exitVal=p.exitValue();
//Do clean up
dis.close();
err.close();
p.destroy();
System.out.println("Iteration "+i);
System.out.println("StdErr = "+StdError);
System.out.println("StdOut = " +StdOut);
System.out.println("___________________________________________________________________");
}catch(Exception exc){
exc.printStackTrace();
}
}
}
You will notice that most of the time stdout and stderr are empty.
If you increase the first thread.sleep() to 2000 milliseconds everything
comes out as it should, because the process has enough time to run.
The best "bug fix" would be do have a reliable way to tell when
the process has completed, and then get all the output from the process
at one time. But until such a time, we need a fix for Process.exitValue().
(Review ID: 56617)
======================================================================