MuntashirAkon/AppManager · error · IOException
Stream closed
Error message
Stream closed
What it means
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.
Source
Thrown at app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java:618
return this.blockSize100k;
}
@Override
public void write(final byte[] buf, int offs, final int len)
throws IOException {
if (offs < 0) {
throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
}
if (len < 0) {
throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
}
if (offs + len > buf.length) {
throw new IndexOutOfBoundsException("offs(" + offs + ") + len("
+ len + ") > buf.length("
+ buf.length + ").");
}
if (closed) {
throw new IOException("Stream closed");
}
for (final int hi = offs + len; offs < hi;) {
write0(buf[offs++]);
}
}
/**
* Keeps track of the last bytes written and implicitly performs
* run-length encoding as the first step of the bzip2 algorithm.
*/
private void write0(int b) throws IOException {
if (this.currentChar != -1) {
b &= 0xff;
if (this.currentChar == b) {
if (++this.runLength > 254) {
writeRun();
this.currentChar = -1;View on GitHub (pinned to 0152f468fc)
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.
Example fix
// before stream.close(); stream.write(data, 0, data.length); // after stream.write(data, 0, data.length); stream.close();
Defensive patterns
Strategy: try-catch
Validate before calling
if (closed) {
throw new IllegalStateException("compressor already closed");
}
out.write(buf, offs, len); Try / catch
try {
out.write(buf, offs, len);
} catch (IOException e) {
if ("Stream closed".equals(e.getMessage())) {
// lifecycle bug: write after close — re-open or drop the write
} else {
throw e;
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Stream closed
- Closed
- offs(" + offs + ") < 0.
- No InputStream
- Corrupted input, " + name + " value negative
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/42f9d4031bb0802f.
Report an issue: GitHub.