From bed0809030cdc137102ef0c7645aac4a2fd74d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=B6kdemir?= Date: Tue, 13 Oct 2026 00:29:57 +0300 Subject: [PATCH 1/2] fix: catch only expected IO failures --- .../jetty/PutTaskRequestContent.java | 4 +- .../jetty/PutTaskRequestContentTest.java | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java index 026b728cd..a286a0fb3 100644 --- a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java +++ b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java @@ -243,7 +243,7 @@ public Content.Chunk read() { return last; } lockedSetTerminal(Content.Chunk.EOF); - } catch (Exception e) { + } catch (IOException e) { lockedSetTerminal(Content.Chunk.from(e, true)); } } @@ -295,7 +295,7 @@ public boolean rewind() { offsetRemaining = 0; totalRead = 0; return true; - } catch (Exception e) { + } catch (IOException e) { lockedSetTerminal(Content.Chunk.from(e, true)); } diff --git a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java index c904d9ed4..837d9ffb2 100644 --- a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java +++ b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java @@ -28,6 +28,27 @@ import static org.junit.jupiter.api.Assertions.assertThrows; class PutTaskRequestContentTest { + @Test + void readPropagatesUnexpectedRuntimeExceptionsFromChannel() { + ReadableByteChannel channel = new ReadableByteChannel() { + @Override + public int read(ByteBuffer destination) { + throw new IllegalStateException("unexpected read failure"); + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() {} + }; + PutTaskRequestContent content = new PutTaskRequestContent(ByteBufferPool.SIZED_NON_POOLING, () -> channel); + + assertThrows(IllegalStateException.class, content::read); + } + @Test void readPropagatesErrorsFromChannel() { ReadableByteChannel channel = new ReadableByteChannel() { @@ -49,6 +70,52 @@ public void close() {} assertThrows(AssertionError.class, content::read); } + @Test + void rewindPropagatesUnexpectedRuntimeExceptionsFromSeekableChannel() { + SeekableByteChannel channel = new SeekableByteChannel() { + @Override + public int read(ByteBuffer destination) { + return -1; + } + + @Override + public int write(ByteBuffer source) { + return 0; + } + + @Override + public long position() { + return 0; + } + + @Override + public SeekableByteChannel position(long newPosition) { + throw new IllegalStateException("unexpected rewind failure"); + } + + @Override + public long size() { + return 0; + } + + @Override + public SeekableByteChannel truncate(long size) { + return this; + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() {} + }; + PutTaskRequestContent content = new PutTaskRequestContent(ByteBufferPool.SIZED_NON_POOLING, () -> channel); + + assertThrows(IllegalStateException.class, content::rewind); + } + @Test void rewindPropagatesErrorsFromSeekableChannel() { SeekableByteChannel channel = new SeekableByteChannel() { From ecaecd6039dd99231b340d9f2de71f9307e8bbc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=B6kdemir?= Date: Tue, 13 Oct 2026 00:54:13 +0300 Subject: [PATCH 2/2] fix: report failed Jetty rewinds --- .../jetty/PutTaskRequestContent.java | 3 +- .../jetty/PutTaskRequestContentTest.java | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java index a286a0fb3..4117e9e0a 100644 --- a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java +++ b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/PutTaskRequestContent.java @@ -297,9 +297,8 @@ public boolean rewind() { return true; } catch (IOException e) { lockedSetTerminal(Content.Chunk.from(e, true)); + return false; } - - return true; } } } diff --git a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java index 837d9ffb2..99b9432f8 100644 --- a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java +++ b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/PutTaskRequestContentTest.java @@ -18,6 +18,7 @@ */ package org.eclipse.aether.transport.jetty; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.SeekableByteChannel; @@ -25,6 +26,7 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; class PutTaskRequestContentTest { @@ -161,4 +163,50 @@ public void close() {} assertThrows(AssertionError.class, content::rewind); } + + @Test + void rewindReturnsFalseWhenPositionFailsWithIOException() { + SeekableByteChannel channel = new SeekableByteChannel() { + @Override + public int read(ByteBuffer destination) { + return -1; + } + + @Override + public int write(ByteBuffer source) { + return 0; + } + + @Override + public long position() { + return 0; + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + throw new IOException("rewind failed"); + } + + @Override + public long size() { + return 0; + } + + @Override + public SeekableByteChannel truncate(long size) { + return this; + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void close() {} + }; + PutTaskRequestContent content = new PutTaskRequestContent(ByteBufferPool.SIZED_NON_POOLING, () -> channel); + + assertFalse(content.rewind()); + } }