M
molar
Hi guys
I'm using the following code to read the normal and error output of a
system process executed in Windows.
I have been able to destroy a task in the past using
process.getErrorStream().close();
process.getInputStream().close();
process.destroy();
Now, I start two StreamGobbler threads to read the error and normal
output of a process. The problem is, with the two extra threads using
the streams I can no longer destroy the process. I have tried all
combinations of InputStream .close() to try and close the error and
normal output streams. Without the line
br.readline()
in StreamGobbler everything works fine and I can destroy a process.
Its as if the StreamGobbler threads aren't giving up the stream.
Anyone know a fix for this? Thanks.
In class Task:
try
{
process = Runtime.getRuntime() .exec(cmd,null,dir);
}
catch (IOException e)
{
// log failure
}
if (process != null)
{
TaskMonitor taskMonitor = new TaskMonitor(this,10000);
taskMonitor.start();
}
BufferedReader br1 = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
BufferedReader br2 = new BufferedReader(new
InputStreamReader(process.getInputStream()));
// check for error messages
StreamGobbler errorGobbler = new StreamGobbler(br1, Task.OUTPUT_ERROR,
this);
// check for output
StreamGobbler outputGobbler = new StreamGobbler(br2,
Task.OUTPUT_NORMAL, this);
errorGobbler.start();
outputGobbler.start();
try
{
errorGobbler.join();
outputGobbler.join();
exitValue = process.waitFor();
// stop the timeout monitor -- it is no longer required
taskMonitor.interrupt();
}
catch (InterruptedException e)
{
try
{
// PROBLEM HERE --
// have also tried process.getErrorStream().close etc.
br1.close();
br2.close();
process.destroy();
}
catch (IOException ioe)
{
// log this error
}
}
and in the same class
public void handleOutput(int type,ArrayList output)
{
if (!output.isEmpty())
{
if (p_type == Task.OUTPUT_NORMAL)
{
g_taskOutput = (String[]) output.toArray();
}
else if (type == Task.OUTPUT_ERROR)
{
taskErrorOutput = (String[]) output.toArray();
}
}
}
Task monitor calls interrupt on the class when it wakes up after
sleeping for 10000.
Then class StreamGobbler
public class StreamGobbler extends Thread
{
int type;
Task task;
BufferedReader br;
StreamGobbler(BufferedReader br,int type, Task task)
{
br = br;
type = type;
task = task;
}
public void run()
{
ArrayList lines = new ArrayList();
String line = null;
try
{
while ((line = br.readLine()) != null)
{
lines.add(line);
}
br.close();
}
catch (Exception e)
{
// log this error
}
task.handleOutput(type,lines);
}
}
I'm using the following code to read the normal and error output of a
system process executed in Windows.
I have been able to destroy a task in the past using
process.getErrorStream().close();
process.getInputStream().close();
process.destroy();
Now, I start two StreamGobbler threads to read the error and normal
output of a process. The problem is, with the two extra threads using
the streams I can no longer destroy the process. I have tried all
combinations of InputStream .close() to try and close the error and
normal output streams. Without the line
br.readline()
in StreamGobbler everything works fine and I can destroy a process.
Its as if the StreamGobbler threads aren't giving up the stream.
Anyone know a fix for this? Thanks.
In class Task:
try
{
process = Runtime.getRuntime() .exec(cmd,null,dir);
}
catch (IOException e)
{
// log failure
}
if (process != null)
{
TaskMonitor taskMonitor = new TaskMonitor(this,10000);
taskMonitor.start();
}
BufferedReader br1 = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
BufferedReader br2 = new BufferedReader(new
InputStreamReader(process.getInputStream()));
// check for error messages
StreamGobbler errorGobbler = new StreamGobbler(br1, Task.OUTPUT_ERROR,
this);
// check for output
StreamGobbler outputGobbler = new StreamGobbler(br2,
Task.OUTPUT_NORMAL, this);
errorGobbler.start();
outputGobbler.start();
try
{
errorGobbler.join();
outputGobbler.join();
exitValue = process.waitFor();
// stop the timeout monitor -- it is no longer required
taskMonitor.interrupt();
}
catch (InterruptedException e)
{
try
{
// PROBLEM HERE --
// have also tried process.getErrorStream().close etc.
br1.close();
br2.close();
process.destroy();
}
catch (IOException ioe)
{
// log this error
}
}
and in the same class
public void handleOutput(int type,ArrayList output)
{
if (!output.isEmpty())
{
if (p_type == Task.OUTPUT_NORMAL)
{
g_taskOutput = (String[]) output.toArray();
}
else if (type == Task.OUTPUT_ERROR)
{
taskErrorOutput = (String[]) output.toArray();
}
}
}
Task monitor calls interrupt on the class when it wakes up after
sleeping for 10000.
Then class StreamGobbler
public class StreamGobbler extends Thread
{
int type;
Task task;
BufferedReader br;
StreamGobbler(BufferedReader br,int type, Task task)
{
br = br;
type = type;
task = task;
}
public void run()
{
ArrayList lines = new ArrayList();
String line = null;
try
{
while ((line = br.readLine()) != null)
{
lines.add(line);
}
br.close();
}
catch (Exception e)
{
// log this error
}
task.handleOutput(type,lines);
}
}