Note that there are some explanatory texts on larger screens.

plurals
  1. POExec'ing multiple processes from Java: outputs mixed up?
    primarykey
    data
    text
    <p>I have a servlet which creates a new Action object inside doGet(), and this object uses exec() to run external processes. There may be several requests to the servlet at the same time, so I might have several Action objects where each one is running an external process at the same time. Occasionally when this happens I find that the output from one process gets mixed up with the output from one of the others.</p> <p>Each Action creates a unique temporary directory and runs the process with this as its current directory. Separate threads then read the output streams from the process into a string buffer. The code that the Action object executes looks basically like this:</p> <pre><code>Process proc = null; ReaderThread stdout = null; ReaderThread stderr = null; StringBuffer buff = new StringBuffer(); int exit = -1; try { // // Run the process // proc = Runtime.getRuntime().exec(command,null,directory); // // Read the output from the process // stdout = new ReaderThread(proc.getInputStream(),buff); stderr = new ReaderThread(proc.getErrorStream(),buff); stdout.start(); stderr.start(); // // Get the exit code // exit = proc.waitFor(); // // Wait for all the output to be read // stdout.join(); stderr.join(); } catch (InterruptedException e) { if (proc != null) { proc.destroy(); } } catch (Exception e) { buff.append(e.getClass() + ": " + e.getMessage()); if (proc != null) { proc.destroy(); } } </code></pre> <p>So each request uses a separate Action object to run a process, and this has its own StringBuffer "buff" that the output of the process is accumulated into by the two ReaderThreads. But what I find is that, when two requests are running two processes at the same time, the output of one will sometimes end up in the StringBuffer of the thread that is running the other one, and one of the two servlet requests will see output intended for the other one. It basically behaves as if Runtime.exec() provides a single global pipe to which the output streams of all the processes are connected.</p> <p>The ReaderThread looks like this:</p> <pre><code>public class ReaderThread extends Thread { private BufferedReader reader; private StringBuffer buffer; public ReaderThread (InputStream stream, StringBuffer buffer) { this.reader = new BufferedReader(new InputStreamReader(stream)); this.buffer = buffer; } @Override public void run () { try { String line; while ((line = reader.readLine()) != null) { synchronized (buffer) { buffer.append(line + "\n"); } } } catch (IOException e) { synchronized (buffer) { buffer.append(e.getMessage() + "\n"); } } } } </code></pre> <p>Can anyone suggest what I can do to fix this?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload