[
https://issues.apache.org/jira/browse/CODEC-334?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18064950#comment-18064950
]
Shan Jiang commented on CODEC-334:
----------------------------------
Thanks for looking into this, Gary. You're right that
AbstractBaseNOutputStreamTest.testClose() passes — but it wraps a
ByteArrayOutputStream, whose close() is a no-op. The idempotency violation
surfaces when the underlying stream enforces single-close semantics:
@Test
void testCloseIdempotentWithFileStream() throws Exception {
Path tmp = Files.createTempFile("codec-test", ".bin");
try {
BaseNCodecOutputStream out = new Base64OutputStream(
new FileOutputStream(tmp.toFile()));
out.close();
out.close(); // IOException: Stream Closed
} finally {
Files.deleteIfExists(tmp);
}
}
The second close() calls flush() then out.close() unconditionally — when out is
a FileOutputStream that's already closed, the flush() (or the inner
out.close()) throws. A guard like if (closed) return; at the top of close()
would fix it.
Apologies that the original report didn't include a concrete test case.
> BaseNCodecOutputStream.close() throws on second call; violates Closeable
> idempotency contract
> ---------------------------------------------------------------------------------------------
>
> Key: CODEC-334
> URL: https://issues.apache.org/jira/browse/CODEC-334
> Project: Commons Codec
> Issue Type: Bug
> Reporter: Shan Jiang
> Priority: Major
>
> ### Summary
> `BaseNCodecOutputStream.close()` is not idempotent: the second call attempts
> to flush to an already-closed underlying stream, throwing `IOException`. The
> `Closeable` contract (JDK 21 Javadoc) states: "If the stream is already
> closed then invoking this method has no effect."
> ### How this was found
> Detected by automated JDK conformance oracle (`checkCloseIdempotent`).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)