From e5be10d53defdff5b353a85555104c56d2865d7c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 4 Jun 2024 23:43:10 +0200 Subject: [PATCH 1/3] Consistently throw IOException from ReactorNettyClientResponse Aligned with ReactorNettyClientRequest. See gh-32952 --- .../client/ReactorNettyClientRequest.java | 30 +++++++++++-------- .../client/ReactorNettyClientResponse.java | 10 +++++-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java index b399ca27a25..e0f6f805ae1 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java @@ -42,6 +42,7 @@ import org.springframework.util.StreamUtils; * Created via the {@link ReactorNettyClientRequestFactory}. * * @author Arjen Poutsma + * @author Juergen Hoeller * @since 6.1 */ final class ReactorNettyClientRequest extends AbstractStreamingClientHttpRequest { @@ -101,18 +102,8 @@ final class ReactorNettyClientRequest extends AbstractStreamingClientHttpRequest return result; } } - catch (RuntimeException ex) { // Exceptions.ReactiveException is package private - Throwable cause = ex.getCause(); - - if (cause instanceof UncheckedIOException uioEx) { - throw uioEx.getCause(); - } - else if (cause instanceof IOException ioEx) { - throw ioEx; - } - else { - throw new IOException(ex.getMessage(), cause); - } + catch (RuntimeException ex) { + throw convertException(ex); } } @@ -136,6 +127,21 @@ final class ReactorNettyClientRequest extends AbstractStreamingClientHttpRequest } } + static IOException convertException(RuntimeException ex) { + // Exceptions.ReactiveException is package private + Throwable cause = ex.getCause(); + + if (cause instanceof UncheckedIOException uioEx) { + return uioEx.getCause(); + } + else if (cause instanceof IOException ioEx) { + return ioEx; + } + else { + return new IOException(ex.getMessage(), cause); + } + } + private static final class ByteBufMapper implements OutputStreamPublisher.ByteMapper { diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientResponse.java b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientResponse.java index 984166d6cd0..4c314d13383 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientResponse.java @@ -33,6 +33,7 @@ import org.springframework.util.StreamUtils; * {@link ClientHttpResponse} implementation for the Reactor-Netty HTTP client. * * @author Arjen Poutsma + * @author Juergen Hoeller * @since 6.1 */ final class ReactorNettyClientResponse implements ClientHttpResponse { @@ -79,8 +80,13 @@ final class ReactorNettyClientResponse implements ClientHttpResponse { return body; } - body = this.connection.inbound().receive() - .aggregate().asInputStream().block(this.readTimeout); + try { + body = this.connection.inbound().receive().aggregate().asInputStream().block(this.readTimeout); + } + catch (RuntimeException ex) { + throw ReactorNettyClientRequest.convertException(ex); + } + if (body == null) { throw new IOException("Could not receive body"); } From f58c7d80cc44f7d3a18909db418b0fd316b682f7 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 4 Jun 2024 23:44:54 +0200 Subject: [PATCH 2/3] Upgrade to SLF4J 2.0.13, Jetty 12.0.10, Netty 4.1.110, JRuby 9.4.7 --- framework-platform/framework-platform.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index 6b6616e2d42..431ca0bd2a4 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -9,15 +9,15 @@ javaPlatform { dependencies { api(platform("com.fasterxml.jackson:jackson-bom:2.15.4")) api(platform("io.micrometer:micrometer-bom:1.12.6")) - api(platform("io.netty:netty-bom:4.1.109.Final")) + api(platform("io.netty:netty-bom:4.1.110.Final")) api(platform("io.netty:netty5-bom:5.0.0.Alpha5")) api(platform("io.projectreactor:reactor-bom:2023.0.6")) api(platform("io.rsocket:rsocket-bom:1.1.3")) api(platform("org.apache.groovy:groovy-bom:4.0.21")) api(platform("org.apache.logging.log4j:log4j-bom:2.21.1")) api(platform("org.assertj:assertj-bom:3.26.0")) - api(platform("org.eclipse.jetty:jetty-bom:12.0.9")) - api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.9")) + api(platform("org.eclipse.jetty:jetty-bom:12.0.10")) + api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.10")) api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3")) api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.0")) api(platform("org.junit:junit-bom:5.10.2")) @@ -130,7 +130,7 @@ dependencies { api("org.hibernate:hibernate-validator:7.0.5.Final") api("org.hsqldb:hsqldb:2.7.2") api("org.javamoney:moneta:1.4.2") - api("org.jruby:jruby:9.4.6.0") + api("org.jruby:jruby:9.4.7.0") api("org.junit.support:testng-engine:1.0.5") api("org.mozilla:rhino:1.7.14") api("org.ogce:xpp3:1.1.6") @@ -139,7 +139,7 @@ dependencies { api("org.seleniumhq.selenium:htmlunit-driver:2.70.0") api("org.seleniumhq.selenium:selenium-java:3.141.59") api("org.skyscreamer:jsonassert:1.5.1") - api("org.slf4j:slf4j-api:2.0.12") + api("org.slf4j:slf4j-api:2.0.13") api("org.testng:testng:7.9.0") api("org.webjars:underscorejs:1.8.3") api("org.webjars:webjars-locator-core:0.55") From 6c054f88ea48d9faa0a27161b13d03283e1d866f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 5 Jun 2024 00:01:52 +0200 Subject: [PATCH 3/3] Defensively handle UncheckedIOException cause (for NullAway compliance) --- .../http/client/ReactorNettyClientRequest.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java index e0f6f805ae1..b60f37c98ec 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequest.java @@ -131,15 +131,16 @@ final class ReactorNettyClientRequest extends AbstractStreamingClientHttpRequest // Exceptions.ReactiveException is package private Throwable cause = ex.getCause(); - if (cause instanceof UncheckedIOException uioEx) { - return uioEx.getCause(); - } - else if (cause instanceof IOException ioEx) { + if (cause instanceof IOException ioEx) { return ioEx; } - else { - return new IOException(ex.getMessage(), cause); + if (cause instanceof UncheckedIOException uioEx) { + IOException ioEx = uioEx.getCause(); + if (ioEx != null) { + return ioEx; + } } + return new IOException(ex.getMessage(), cause); }