{"record":{"id":"42f9d4031bb0802f","repo":"MuntashirAkon/AppManager","slug":"stream-closed-bzip2compressoroutputstream","errorCode":null,"errorMessage":"Stream closed","messagePattern":"Stream closed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java","lineNumber":618,"sourceCode":"        return this.blockSize100k;\n    }\n\n    @Override\n    public void write(final byte[] buf, int offs, final int len)\n            throws IOException {\n        if (offs < 0) {\n            throw new IndexOutOfBoundsException(\"offs(\" + offs + \") < 0.\");\n        }\n        if (len < 0) {\n            throw new IndexOutOfBoundsException(\"len(\" + len + \") < 0.\");\n        }\n        if (offs + len > buf.length) {\n            throw new IndexOutOfBoundsException(\"offs(\" + offs + \") + len(\"\n                    + len + \") > buf.length(\"\n                    + buf.length + \").\");\n        }\n        if (closed) {\n            throw new IOException(\"Stream closed\");\n        }\n\n        for (final int hi = offs + len; offs < hi;) {\n            write0(buf[offs++]);\n        }\n    }\n\n    /**\n     * Keeps track of the last bytes written and implicitly performs\n     * run-length encoding as the first step of the bzip2 algorithm.\n     */\n    private void write0(int b) throws IOException {\n        if (this.currentChar != -1) {\n            b &= 0xff;\n            if (this.currentChar == b) {\n                if (++this.runLength > 254) {\n                    writeRun();\n                    this.currentChar = -1;","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java#L600-L636","documentation":"After argument validation, write() checks the closed flag and throws IOException(\"Stream closed\") if the BZip2CompressorOutputStream has already been finished or closed. Writing to a closed compressor stream is invalid because the deflate state has been finalized.","triggerScenarios":"Calling write() after close() or finish(); double-closing in try-with-resources followed by manual write; asynchronous writers using a stream another thread already closed.","commonSituations":"Calling close() twice (once explicitly, once via try-with-resources) with more writes in between; lifecycle bugs in code that flushes after shutdown; leaking a closed stream into a callback.","solutions":["Audit the code path and remove writes that occur after close()/finish().","Guard writes with an isOpen/managed lifecycle check in your wrapper.","Ensure exactly one close: rely on try-with-resources and drop manual close calls."],"exampleFix":"// before\nstream.close();\nstream.write(data, 0, data.length);\n// after\nstream.write(data, 0, data.length);\nstream.close();","handlingStrategy":"try-catch","validationCode":"if (closed) {\n    throw new IllegalStateException(\"compressor already closed\");\n}\nout.write(buf, offs, len);","typeGuard":null,"tryCatchPattern":"try {\n    out.write(buf, offs, len);\n} catch (IOException e) {\n    if (\"Stream closed\".equals(e.getMessage())) {\n        // lifecycle bug: write after close — re-open or drop the write\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use try-with-resources so close() happens exactly once, after all writes.","Never interleave manual close() with try-with-resources on the same stream.","In concurrent code, synchronize access or check a lifecycle flag before writing."],"tags":["io","stream-closed","bzip2","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}