This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new cb99c360800 CXF-9251: Thrown exception trying to write into closed
stream (#3555)
cb99c360800 is described below
commit cb99c360800551a5594ea9de2a4f159a16c62734
Author: Andriy Redko <[email protected]>
AuthorDate: Thu Oct 8 11:37:16 2026 -0400
CXF-9251: Thrown exception trying to write into closed stream (#3555)
* CXF-9251: Thrown exception trying to write into closed stream
* Address code review comments
---
.../apache/cxf/ext/logging/LoggingOutputStream.java | 19 +++++++------------
.../cxf/ext/logging/LoggingOutInterceptorTest.java | 6 ++----
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutputStream.java
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutputStream.java
index ac24ac1a528..ab3a3b072fb 100644
---
a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutputStream.java
+++
b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutputStream.java
@@ -82,16 +82,15 @@ public class LoggingOutputStream extends
CacheAndWriteOutputStream {
* This caused ghost/delayed OUT log and possible memory-leak due to
DelayedCachedOutputStreamCleaner
*
* Once closed (and logged), any late write (for example the fault chain
writing the closing tags
- * through a writer still wrapping this stream) is only passed through to
the flow-through stream and
- * is not cached anymore: some containers (e.g. Tomcat 10.1) silently
accept writes after close, and
- * caching them would spill into a new temp file that close() (now a
no-op) could never delete.
+ * through a writer still wrapping this stream) is leading to {@code
IOException} since all underlying
+ * stream are closed: some containers (e.g. Tomcat 10.1) silently accept
writes after close, and
+ * caching them (by letting writes to go through) would spill into a new
temp file that close()
+ * (now a no-op) could never delete.
*/
@Override
public void write(byte[] b) throws IOException {
if (closed.get()) {
- // already closed and logged: pass through only, do not cache again
- getFlowThroughStream().write(b);
- return;
+ throw new IOException("The channel has been closed already");
}
try {
super.write(b);
@@ -104,9 +103,7 @@ public class LoggingOutputStream extends
CacheAndWriteOutputStream {
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (closed.get()) {
- // already closed and logged: pass through only, do not cache again
- getFlowThroughStream().write(b, off, len);
- return;
+ throw new IOException("The channel has been closed already");
}
try {
super.write(b, off, len);
@@ -119,9 +116,7 @@ public class LoggingOutputStream extends
CacheAndWriteOutputStream {
@Override
public void write(int b) throws IOException {
if (closed.get()) {
- // already closed and logged: pass through only, do not cache again
- getFlowThroughStream().write(b);
- return;
+ throw new IOException("The channel has been closed already");
}
try {
super.write(b);
diff --git
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingOutInterceptorTest.java
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingOutInterceptorTest.java
index e94f726432f..bc415a21484 100644
---
a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingOutInterceptorTest.java
+++
b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingOutInterceptorTest.java
@@ -336,8 +336,7 @@ public class LoggingOutInterceptorTest {
// A late writer still holding the old stream reference, with a
flow-through stream that
// accepts writes after close: it must not be cached (and spilled to a
new temp file) again
- cached.write(bytes, 0, bytes.length);
- assertThat(((ByteArrayOutputStream) os).size(), equalTo(2 *
bytes.length));
+ assertThrows(IOException.class, () -> cached.write(bytes, 0,
bytes.length));
final File tempFile = ((CachedOutputStream) cached).getTempFile();
cleaner.forceClean();
@@ -385,8 +384,7 @@ public class LoggingOutInterceptorTest {
// e.g. the fault chain (SoapOutEndingInterceptor) writing the closing
tags through the
// XMLStreamWriter that still wraps this stream, with a flow-through
stream that accepts writes
// after close (as Tomcat 10.1 does): it must not be cached (and
spilled to a new temp file) again
- cached.write(bytes, 0, bytes.length);
- assertThat(((ByteArrayOutputStream) os).size(), equalTo(2 *
bytes.length));
+ assertThrows(IOException.class, () -> cached.write(bytes, 0,
bytes.length));
final File tempFile = ((CachedOutputStream) cached).getTempFile();
cleaner.forceClean();