#17 Jester hangs on Mac

open
nobody
None
5
2005-01-29
2005-01-29
No

Stepping through with the debugger I find Jester hangs
on the Mac at the last line of this code fragment:

public class Util {
public static Vector runCommand(String[] cmd, Logger
aLogger) throws IOException {

StringBuffer sb = new StringBuffer(cmd[0]);
for (int i = 1; i < cmd.length; i++) {
sb.append(' ');
sb.append(cmd[i]);
}
String commandLine = sb.toString();

aLogger.log("Trying to run command \"" + commandLine
+ "\"");
Process proc = Runtime.getRuntime().exec(cmd);

BufferedReader br = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader err = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));

Vector output = new Vector();
String str;
while ((str = br.readLine()) != null) {

There are two possibilities:

1. The Mac Runtime/Process is not behaving like you
expect and therefore readLine() never returns
2. readLine in BufferedReader is not noticing thr Mac's
end of line character. This is a longstanding issue
with readLine.

I'm ot yet sure which (or perhaps both) is causing the
problem. However, I rfecommend removing both; i.e.

1. Don't use BufferedReader.readLine, at all. If you
need more details about why not and how to avoid it,
holler and I'll send you a copy of Java Network
Programming where I lay out all the problems, but the
bottom line is this method should *never* be used

2. Don't use Runtime or Process. These are severely
platform dependent. Invoke the necessary classes
directly. JUnit and Javac are written in Java. They can
be called from Java without going through Runtime.exec.

Discussion

  • Sean Dockery

    Sean Dockery - 2006-10-15

    Logged In: YES
    user_id=879771

    Actually, there is a third possibility that I am witnessing
    on Windows XP. The sub-process is blocking on a call to
    System.err because the error buffer has filled up.

    We modified the Util.runCommand method slightly to collect
    stderr output from the sub-process in another thread. At
    the point in the runCommand method where it was attempting
    to pull output from stderr of the sub-process, we replace
    that section with a call to join the stderr collecting
    thread I just mentioned and simply output what we had
    collected. That took care of the hang.

     
  • Sean Dockery

    Sean Dockery - 2006-10-17

    Logged In: YES
    user_id=879771

    I have submitted a patch to make the change that I described.

     
  • Miguel Ferreira

    Miguel Ferreira - 2010-12-13

    In addition to Macs I found that this issue also arises in Linux when there is too much error output (as pointed out by dockerysean).

    From my experience I found that it is always good to read the output and errors streams for a Process in different threads.
    I tried this for this case and it seems to work.

    Here is a prototype of the modified method, in case you want to use it:

    public static Vector<String> runCommand(final String commandLine, final Logger aLogger) throws IOException {
    aLogger.log("Trying to run command \"" + commandLine + "\"");
    final Process proc = Runtime.getRuntime().exec(commandLine);
    final Vector<String> output = new Vector<String>();

    Thread outputCollector = new Thread(new Runnable() {

    @Override
    public void run() {
    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    String str;
    try {
    while ((str = br.readLine()) != null) {
    output.addElement(str);
    }
    br.close();
    } catch (IOException e) {
    e.printStackTrace();
    aLogger.log("IO error while reading process '" + commandLine + "' output.");
    }

    }
    });

    Thread errorCollector = new Thread(new Runnable() {

    @Override
    public void run() {
    BufferedReader err = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
    String str;
    boolean firstLine = true;
    try {
    while ((str = err.readLine()) != null) {
    if (firstLine) {
    System.out.println("ERR> NOTE - jester has tried to 'exec' \"" + commandLine + "\"");
    }
    // XXX see bug 1346212
    firstLine = false;
    System.out.println("ERR> " + str);
    }
    err.close();
    } catch (IOException e) {
    e.printStackTrace();
    aLogger.log("IO error while reading process '" + commandLine + "' error output.");
    }

    }
    });

    outputCollector.start();
    errorCollector.start();

    try {
    proc.waitFor();
    outputCollector.join();
    errorCollector.join();
    } catch (InterruptedException e) {
    aLogger.log("process was interrupted for " + commandLine);
    }

    aLogger.log("running command \"" + commandLine + "\" resulted in \"" + output + "\"");

    return output;
    }

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks