Defensive copy of streams and process

134 Views Asked by At

I'm having an Process proc running which I need to destroy and recreate if an error occurs.
That is because of an issue with sending commands via stdin to the process which it can't resolve.
My workaround is to reset the "connection" I built(stdin,stdout,stderr) and get new streams from the new process. I'm using a thread to watch, when the process ends. If an error occurs, I shut the process down via a quit-command and interrupt the thread which causes it to finally close the streams.
The main-thread is already building up a new connection. When sending a command after rebuilding the connection an IOException states the stream is closed.
Is there a way I could copy the old stream to close it later on? I already tried it with wrapping it with another Reader but didn't succeed. I'm not sure if it's enough to get the process' streams via getXXXStream() and close them because this wouldn't close the readers above. Also I'm afraid, I could grab the new process and close it's streams.
I don't want it to block though.
EDIT:
As my first comment states, I close the streams immediately, but the problem with the Process remains. If I'm waiting 1000 ms for it to close and reassign proc with the new Process my thread operates with the new one (e.g. calls exitValue()).

Here's my Thread:

private class ProcEndWatcherThread extends Thread
{
    private BufferedReader out, err;
    private PrintWriter wr;

    public ProcEndWatcherThread(BufferedReader out, BufferedReader err,  `PrintWriter wr)`
    {
        this.out = out;
        this.err = err;
        this.wr = wr;

        //this.out = new BufferedReader(out);
        //this.err = new BufferedReader(err);
        //this.wr = new PrintWriter(wr);
    }
    @Override
    public void run()
    {
        boolean closed = false;
        try
        {
            isRunning = true;
            proc.waitFor();
            closed = true;
        }
        catch (InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
        finally
        {
            if(!closed)
                proc.destroy();         

            try {
                out.close();
                err.close();
            } catch (IOException e) {
                log.throwing("ProcEndWatcherThread", "run", e);
            }
            wr.close();
            isRunning = false;
            log.info("Exitvalue: " + proc.exitValue());
        }
    }
}

The method to build my connection(connect + reconnect):

private void initCon() throws RException, IOException
{
            proc = new ProcessBuilder(pathAndArgs).start();
            System.out.println(proc.toString());
            errRd = new BufferedReader(new InputStreamReader(
                    proc.getErrorStream()));
            outRd = new BufferedReader(new InputStreamReader(
                    proc.getInputStream()));
            BufferedWriter inWr = new BufferedWriter(new


OutputStreamWriter(new BufferedOutputStream(
                        proc.getOutputStream())));
            pWr = new PrintWriter(inWr);

            procEndWatcherThread = new ProcEndWatcherThread(outRd, errRd, pWr);
            procEndWatcherThread.start();
... some initializing
}
0

There are 0 best solutions below