0

Before accusing of duplicate, please, read the question.

I've a web application that starts multiple Threads, each Thread need to read various InputStreams, parsing them to Strings to extract information. The stream is from a org.apache.http.HttpResponse:

response.getEntity().getContent();

I've implemented the following code that receives the InputStream:

    int len, size = 1024;
    byte[] buf;

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    buf = new byte[size];
    while ((len = is.read(buf, 0, size)) != -1)
        bos.write(buf, 0, len);

    return bos.toString(encode);

For some reason this method simply stops processing, and, obviously, don't finishes reading the stream. Consequently, the Thread never finishes and also blocks the other Threads to execute. On the other hand, the web application keeps "alive" accepting new requests (new Threads). Moreover, this only happens when I run locally, but not on the Production server, where the application is running (luck?).

For testing purposes I changed the method:

    // ...
    System.out.println("\n=------------------------------");
    while (true) {
        len = is.read(buf, 0, size);
        System.out.print(len);
        if (len == -1)
            break;
        bos.write(buf, 0, len);
        System.out.print(" ");
    }
    System.out.println("\n=------------------------------");
    // ...

Which produced:

[...]
=------------------------------ 
1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 1024 1024 1024 1024 305 1024 404 1024 404 1024 216 1024 404 1024 404 1024 216 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 131 -1 
=------------------------------

=------------------------------ 
1024 404 1024 404 1024 216 1024 404 1024 404 1024 404 1024 404 1024 404 1024 28 1024 404 1024 404 1024 404 1024 22 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 1024 404 

with an space in the end, what means that the method stopped at line len = is.read(buf, 0, size);. None exception was thrown (I surrounded with a try-catch block, catching a Throwable).

This behavior is random, what means that the same stream (maybe not exactly the same, but from the same requested url) may or may not cause the bug. Restarting the application and the Threads I could execute some that previously had failed, until the problem, sooner or later, occurred again.

Reading other StackOverflow's questions, someone pointed an BufferedInputStream, so I changed:

    BufferedInputStream buffIs = new BufferedInputStream(is);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    buf = new byte[size];
    while (true) {
        len = buffIs.read(buf);
        if (len == -1)
            break;
        bos.write(buf, 0, len);
    }

    return bos.toString();

This almost solved the problem, I could execute various Threads without trouble, but still the bug persisted.

I also read Why InputStream is stopping my application? and Is it possible to read from a InputStream with a timeout?. But the environment and the output were different and, as I need to extract information of the generated Strings, setting a wrapping timeout function don't seems a good choice, because I won't have the entire content of the stream, and I may loose some good information.

Any idea of why this happens? I am stuck on this and wasn't able to come up with a proper solution.

[edit]
Before all this, I was using IOUtils.toString(inputStream, "ISO-8859-1"), where the bug started and I tried to implement my own method.;

--
Sorry for any misspelling, feel free to correct me.

Community
  • 1
  • 1
Luiz
  • 76
  • 6

0 Answers0