R
Ron
I'll put my source code and the exception below, but here is an
outline and my theory:
I'm using ProcessBuilder to create and start an external process. I'm
creating threads to service the i/o in the usual way. Occassionally
when reading process output I get an IOException because the stream
is closed. I have not closed the stream from the java side.
I am assuming that the stream will also close if the process
completes. I think maybe the process finishes, the stream gets
closed, my java program attempts to read the next line of output and
gets the IOException. I think the timing has to be just right though,
because given the same command, I sometimes see the exception and
sometimes not. I also thought that maybe the process is not outputing
an EOF before exiting as a possible cause, but that doesn't really
explain why, for the same command, I sometimes get the exception, and
sometimes do not.
Has anyone else observed this before? Is it possible for the stream
to get closed because the process has exited? Or should it only close
when I explicitly close it in the java program? What do you believe
is the root cause of the exception? Is there anyway to avoid the
exception in the case where the process has completed and really
everything is fine, but still get an exception if the stream closed
for other reasons?
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen
(BufferedInputStream.java:145)
at java.io.BufferedInputStream.read(BufferedInputStream.java:
308)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at com.nortel.utilities.ProcessUtilities$1.run
(ProcessUtilities.java:101)
public static void exec( List<String> command,
final List<String> stdOut )
{
ProcessBuilder pb = new ProcessBuilder( command );
final Process p = pb.start();
new Thread()
{
public void run()
{
final BufferedReader stdOutReader = new BufferedReader
( new InputStreamReader( p.getInputStream() ), 1024 );
String line;
try
{
while( ( line = stdOutReader.readLine() ) != null )
{
if( stdOut != null )
{
stdOut.add( line );
}
}
stdOutReader.close();
}
catch( IOException ex )
{
Logger.getLogger( ProcessUtilities.class.getName() ).log
( Level.SEVERE, null, ex );
}
}
}.start();
try
{
p.waitFor();
}
catch( InterruptedException e )
{
Thread.currentThread().interrupt();
}
}
outline and my theory:
I'm using ProcessBuilder to create and start an external process. I'm
creating threads to service the i/o in the usual way. Occassionally
when reading process output I get an IOException because the stream
is closed. I have not closed the stream from the java side.
I am assuming that the stream will also close if the process
completes. I think maybe the process finishes, the stream gets
closed, my java program attempts to read the next line of output and
gets the IOException. I think the timing has to be just right though,
because given the same command, I sometimes see the exception and
sometimes not. I also thought that maybe the process is not outputing
an EOF before exiting as a possible cause, but that doesn't really
explain why, for the same command, I sometimes get the exception, and
sometimes do not.
Has anyone else observed this before? Is it possible for the stream
to get closed because the process has exited? Or should it only close
when I explicitly close it in the java program? What do you believe
is the root cause of the exception? Is there anyway to avoid the
exception in the case where the process has completed and really
everything is fine, but still get an exception if the stream closed
for other reasons?
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen
(BufferedInputStream.java:145)
at java.io.BufferedInputStream.read(BufferedInputStream.java:
308)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at com.nortel.utilities.ProcessUtilities$1.run
(ProcessUtilities.java:101)
public static void exec( List<String> command,
final List<String> stdOut )
{
ProcessBuilder pb = new ProcessBuilder( command );
final Process p = pb.start();
new Thread()
{
public void run()
{
final BufferedReader stdOutReader = new BufferedReader
( new InputStreamReader( p.getInputStream() ), 1024 );
String line;
try
{
while( ( line = stdOutReader.readLine() ) != null )
{
if( stdOut != null )
{
stdOut.add( line );
}
}
stdOutReader.close();
}
catch( IOException ex )
{
Logger.getLogger( ProcessUtilities.class.getName() ).log
( Level.SEVERE, null, ex );
}
}
}.start();
try
{
p.waitFor();
}
catch( InterruptedException e )
{
Thread.currentThread().interrupt();
}
}