#5 RecordStoreAppender fails with java.lang.RuntimeException: W

v1.1
closed-fixed
5
2009-02-27
2009-02-26
Reiner Saddey
No

Applies to:

Both Version 1.0.0 and current trunk (at revision 721).

Symptom:

Only the first log request succeeeds. Subsequent requests fail with "java.lang.RuntimeException: Writing to closed ByteArrayOutputStream."

Cause:

Within method createLogData RecordStoreAppender closes its dataOutputStream on each log request, causing all but the first log request to fail.

Neither dataOutputStream nor byteArrayOutputStream must be closed (not even within method close()), as they are created within the constructor and assumed to be available forever.

Fix:

Just remove the "dataOutputStream.close();" from method createLogData.

Notes:

1. As DataOutputStream uses the decorator pattern, its close() will delegated to its decorated OutputStream.

2. jaywayjohan and k_o_ appear not to be able to agree upon as to whether dataOuputStream and byteArrayOutputStream should be class fields or local variables.

Discussion

  • Johan Karlsson
    Johan Karlsson
    2009-02-26

    • assigned_to: nobody --> jaywayjohan
     
  • Johan Karlsson
    Johan Karlsson
    2009-02-26

    I will fix this ASAP.

     
  • If resource usage is a concern, the code might be changed to create the streams within method open() and close (and nullify) them within method close(). The actual code location should be next to the logOpen = true/false statements within open() and close().

    The current code somewhat defeats its own concept of a master appender, because both byteArrayOutputStream and dataOutputStream are created within the contructor of RecordStoreAppender. If the actual instance happens to be a non-master, its streams will never be used at all.

    I think the choice for the streams to be implemented as class fields or local variables is not obvious. Creating new streams on every log will keep the garbage collector somewhat busy. Keeping the streams alive might waste a couple of bytes within the byteArrayOutputStream (its internal array will be sized to accommodate the largest amount of data actually written, it will never shrink, not even with reset() or close()).

     
  • Johan Karlsson
    Johan Karlsson
    2009-02-27

    I removed the close() method since closing a ByteArrayOutputStream is not doing anything. The streams are member variables and should be. No need to create new stream each time we create new log data.

     
  • Johan Karlsson
    Johan Karlsson
    2009-02-27

    • milestone: --> v1.1
    • status: open --> closed-fixed