I am trying to pass data from a program MainProgram
to another program TestProgram
which I invoke using Reflection. For this, i re-route Standard.in
to a ByteArrayOutputStream
containing the data I want to transmit. TestProgram
then reads from Standard.in
using a BufferedReader
and readLine()
. I execute the whole thing several times in a for-loop. The problem is this: The first time, everything works fine, from the second time on, TestProgram
reads null
from System.in
. Java Documentation states that the BufferedReader
will return null
, if the end of stream is reached. But there is definitely data in the stream and the pos
of my ByteArrayOutputStream
is also 0. Why could the BufferedReader
think that suddenly System.in
is empty or at the end of stream?
Here is the code that's manipulating the streams and invoking the method:
for(int i = 0; i < numberOfCases; i++) {
Byte[] paramBytes = getCurrentParamBytes();
InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream(paramBytes));
System.setIn(inputStream);
String[] params = null;
testProgram.invoke(null, (Object) params);
}
Here is the code that's reading from System.in
:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String current = in.readLine();
I have assured myself of the state of System.in
using the debugging mode of Eclipse and everything is fine there. The fact that it only reads null
starting with the second invocation of the TestProgram
's main method is also very puzzling to me. Especially, because all values I have checked are exactly the same as they were the first time (except for the data in the stream, of course).
Sadly, I cannot change the use of the BufferedReader
because TestProgram
is not my class and has to be used as-is.
Any help would be greatly appreciated.
The problem is likely in the fact that
BufferedReader
created once, on first invocation.BufferedReader
uses instance ofInputStream
that you provided on first iteration of a loop. On second, third, etc invocations it still uses this stream and doesn't read from updatedSystem.in
. I see 2 possible solutions if you can't modify source code ofTestProgram
.TestProgram
on each iteration instead of reusing old. It might help to "refresh" innerBufferedReader
if it is stored as class variable, not static.TestProgram
because it has state orBufferedReader
stored in static variable you can try following: use special kind ofInputStream
that allows you to concatenate severalInputStreams
on fly. Check ConcatInputStream.Example of second approach:
I'm not sure it will work because I don't know what is behaviour of BufferedReader if it sees end of stream on first invocation and then, on second invocation, stream suddenly not empty any more (because we've added new stream to
concat
). But hopefully it will work.There are also third approach: you can decompile
TestProgram
using e.g. JD and find where instance ofBufferedReader
is stored. And then you can set it to null between iterations using reflections. But it's very error prone.