MuntashirAkon/AppManager · error · IOException
Closed
Error message
Closed
What it means
write(int) checks whether the output stream has already been closed; writing after close() is an invalid state and throws IOException("Closed"). A closed BZip2CompressorOutputStream has finalized the bzip2 stream and cannot accept more data.
Source
Thrown at app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java:383
if (blockSize < 1) {
throw new IllegalArgumentException("blockSize(" + blockSize + ") < 1");
}
if (blockSize > 9) {
throw new IllegalArgumentException("blockSize(" + blockSize + ") > 9");
}
this.blockSize100k = blockSize;
this.out = out;
/* 20 is just a paranoia constant */
this.allowableBlockSize = (this.blockSize100k * BZip2Constants.BASEBLOCKSIZE) - 20;
init();
}
@Override
public void write(final int b) throws IOException {
if (closed) {
throw new IOException("Closed");
}
write0(b);
}
/**
* Writes the current byte to the buffer, run-length encoding it
* if it has been repeated at least four times (the first step
* RLEs sequences of four identical bytes).
*
* <p>Flushes the current block before writing data if it is
* full.</p>
*
* <p>"write to the buffer" means adding to data.buffer starting
* two steps "after" this.last - initially starting at index 1
* (not 0) - and updating this.last to point to the last index
* written minus 1.</p>
*/
private void writeRun() throws IOException {View on GitHub (pinned to 0152f468fc)
Solutions
- Stop writing after close(); restructure so close() happens only when all data is written.
- Open a new BZip2CompressorOutputStream for additional data instead of reusing a closed one.
- Ensure only one owner closes the stream (try-with-resources around the entire write path).
- Guard with an isClosed()/closed flag check before writing if lifecycle is complex.
Example fix
// before
try (BZip2CompressorOutputStream b = new BZip2CompressorOutputStream(fos)) {
b.write(header);
}
b.write(footer); // stream already closed -> IOException: Closed
// after
try (BZip2CompressorOutputStream b = new BZip2CompressorOutputStream(fos)) {
b.write(header);
b.write(footer);
} Defensive patterns
Strategy: try-catch
Try / catch
if (!closed) {
try { stream.write(b); } catch (IOException e) {
if ("Closed".equals(e.getMessage())) throw new IllegalStateException("write after close", e);
throw e;
}
} Prevention
- Use try-with-resources so all writes happen inside the open scope
- Have a single owner responsible for closing the stream
- Never cache and reuse compressor streams after a completed unit of work
- Track closed state in wrapper classes and fail early with a clear error
When it happens
Trigger: Calling write(byte), write(byte[]), or close()-dependent wrappers after close() was invoked — e.g. writing via the same reference twice, try-with-resources followed by manual writes, or a copied reference to a stream closed elsewhere.
Common situations: Double-close in layered stream code, buffering writes after try-with-resources scope ends, a utility method closing the caller's stream then the caller writing more, caching the stream in a field after a completed unit of work.
Related errors
- Stream closed
- Stream 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/9a07482a3d916b29.
Report an issue: GitHub.