From 2b9010c2a2a29fbbe0f84d409885a92477007abd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 4 Dec 2024 13:19:39 +0100 Subject: [PATCH] Remove APIs marked as deprecated for removal Closes gh-33809 --- .../ROOT/pages/web/webflux/config.adoc | 7 +- .../webmvc/mvc-config/static-resources.adoc | 7 +- framework-platform/framework-platform.gradle | 2 - .../AsyncExecutionAspectSupport.java | 4 - .../AnnotationAsyncExecutionAspectTests.java | 13 +- .../factory/aot/BeanInstanceSupplier.java | 24 - .../support/SimpleInstantiationStrategy.java | 17 - .../aot/BeanInstanceSupplierTests.java | 23 - .../quartz/SimpleThreadPoolTaskExecutor.java | 22 +- .../ApplicationListenerMethodAdapter.java | 4 - .../scheduling/annotation/AsyncResult.java | 43 +- .../concurrent/ConcurrentTaskExecutor.java | 27 +- .../concurrent/ConcurrentTaskScheduler.java | 12 - .../concurrent/SimpleAsyncTaskScheduler.java | 12 - .../concurrent/ThreadPoolTaskExecutor.java | 34 +- .../concurrent/ThreadPoolTaskScheduler.java | 57 +-- .../method/MethodValidationResult.java | 13 - .../method/ParameterValidationResult.java | 29 -- .../AnnotationDrivenEventListenerTests.java | 19 - ...AsyncAnnotationBeanPostProcessorTests.java | 24 - .../annotation/AsyncExecutionTests.java | 38 -- .../annotation/AsyncResultTests.java | 110 ----- .../AbstractSchedulingTaskExecutorTests.java | 123 +----- .../ConcurrentTaskExecutorTests.java | 4 +- .../ConcurrentTaskSchedulerTests.java | 18 +- .../DecoratedThreadPoolTaskExecutorTests.java | 4 +- .../SimpleAsyncTaskSchedulerTests.java | 17 +- .../ThreadPoolTaskExecutorTests.java | 5 +- .../ThreadPoolTaskSchedulerTests.java | 4 +- .../FilePatternResourceHintsRegistrar.java | 70 +-- .../task/AsyncListenableTaskExecutor.java | 58 --- .../core/task/SimpleAsyncTaskExecutor.java | 22 +- .../task/support/TaskExecutorAdapter.java | 32 +- .../org/springframework/util/MimeType.java | 45 -- .../springframework/util/MimeTypeUtils.java | 11 +- .../util/PropertyPlaceholderHelper.java | 18 - .../CompletableToListenableFutureAdapter.java | 110 ----- .../util/concurrent/FailureCallback.java | 40 -- .../util/concurrent/ListenableFuture.java | 74 ---- .../concurrent/ListenableFutureAdapter.java | 86 ---- .../concurrent/ListenableFutureCallback.java | 36 -- .../ListenableFutureCallbackRegistry.java | 157 ------- .../util/concurrent/ListenableFutureTask.java | 107 ----- .../MonoToListenableFutureAdapter.java | 40 -- .../concurrent/SettableListenableFuture.java | 192 -------- .../util/concurrent/SuccessCallback.java | 43 -- ...ilePatternResourceHintsRegistrarTests.java | 6 +- .../concurrent/ListenableFutureTaskTests.java | 138 ------ .../MonoToListenableFutureAdapterTests.java | 74 ---- .../SettableListenableFutureTests.java | 414 ------------------ .../expression/spel/ExpressionState.java | 58 --- .../expression/spel/ast/Indexer.java | 11 - .../expression/spel/ExpressionStateTests.java | 92 ---- .../AsyncHandlerMethodReturnValueHandler.java | 29 -- .../ListenableFutureReturnValueHandler.java | 49 --- .../SimpAnnotationMethodMessageHandler.java | 2 - .../stomp/ConnectionHandlingStompSession.java | 11 - .../stomp/ReactorNettyTcpStompClient.java | 34 -- .../messaging/tcp/TcpConnection.java | 14 - .../messaging/tcp/TcpOperations.java | 45 -- ...mpAnnotationMethodMessageHandlerTests.java | 63 --- .../test/util/JsonPathExpectationsHelper.java | 12 - .../reactive/server/DefaultWebTestClient.java | 7 - .../web/reactive/server/ExchangeResult.java | 10 - .../reactive/server/JsonPathAssertions.java | 21 - .../web/reactive/server/WebTestClient.java | 13 - .../samples/client/standalone/AsyncTests.java | 19 - .../samples/standalone/AsyncTests.java | 28 -- .../reactive/GenericReactiveTransaction.java | 9 +- .../support/DefaultTransactionStatus.java | 9 +- spring-web/spring-web.gradle | 1 - .../org/springframework/http/HttpHeaders.java | 15 - .../org/springframework/http/MediaType.java | 156 ------- .../http/client/ClientHttpResponse.java | 13 - ...ttpComponentsClientHttpRequestFactory.java | 12 - .../http/client/OkHttp3ClientHttpRequest.java | 142 ------ .../OkHttp3ClientHttpRequestFactory.java | 153 ------- .../client/OkHttp3ClientHttpResponse.java | 94 ---- .../http/client/ReactorClientHttpRequest.java | 18 - .../ReactorClientHttpRequestFactory.java | 30 -- .../client/ReactorClientHttpResponse.java | 17 - .../ReactorNettyClientRequestFactory.java | 58 --- .../SimpleClientHttpRequestFactory.java | 34 +- .../client/reactive/ClientHttpResponse.java | 12 - .../ReactorNetty2ServerHttpResponse.java | 8 - .../reactive/ReactorServerHttpResponse.java | 8 - .../server/reactive/ServerHttpResponse.java | 16 +- .../reactive/ServerHttpResponseDecorator.java | 8 - .../reactive/ServletServerHttpResponse.java | 8 - .../reactive/UndertowServerHttpResponse.java | 8 - ...ssingServletRequestParameterException.java | 21 +- .../client/DefaultResponseErrorHandler.java | 40 -- .../web/client/ResponseErrorHandler.java | 15 +- .../reactive/ServerHttpObservationFilter.java | 176 -------- .../ResponseStatusExceptionHandler.java | 20 +- .../AbstractReactorHttpExchangeAdapter.java | 51 +-- .../service/invoker/HttpClientAdapter.java | 147 ------- .../util/ContentCachingRequestWrapper.java | 15 - .../web/util/UriComponentsBuilder.java | 29 -- .../springframework/http/MediaTypeTests.java | 216 --------- ...ientHttpRequestFactoryWithOkHttpTests.java | 31 -- .../OkHttp3ClientHttpRequestFactoryTests.java | 41 -- .../client/RestClientIntegrationTests.java | 2 - .../client/RestTemplateIntegrationTests.java | 2 - .../ServerHttpObservationFilterTests.java | 142 ------ spring-webflux/spring-webflux.gradle | 1 - .../config/ResourceChainRegistration.java | 16 +- .../ClientRequestObservationContext.java | 10 - .../function/client/ClientResponse.java | 11 - .../server/DefaultServerResponseBuilder.java | 7 - .../function/server/ServerResponse.java | 9 - .../server/support/RouterFunctionMapping.java | 7 +- .../handler/AbstractUrlHandlerMapping.java | 5 +- .../resource/WebJarsResourceResolver.java | 125 ------ .../RequestMappingInfoHandlerMapping.java | 5 +- .../result/view/FragmentsRendering.java | 60 --- ...ientRequestObservationConventionTests.java | 12 - .../DefaultEntityResponseBuilderTests.java | 4 +- .../DefaultServerResponseBuilderTests.java | 4 +- .../function/server/RouterFunctionsTests.java | 10 - .../support/RouterFunctionMappingTests.java | 7 +- .../WebJarsResourceResolverTests.java | 155 ------- spring-webmvc/spring-webmvc.gradle | 1 - .../web/servlet/DispatcherServlet.java | 32 +- .../config/ResourcesBeanDefinitionParser.java | 8 +- .../annotation/ResourceChainRegistration.java | 16 +- .../function/AbstractServerResponse.java | 9 +- .../CompletedAsyncServerResponse.java | 11 +- .../function/DefaultAsyncServerResponse.java | 10 +- .../web/servlet/function/ServerResponse.java | 8 - .../servlet/handler/MappedInterceptor.java | 14 +- ...eferredResultMethodReturnValueHandler.java | 25 +- .../resource/WebJarsResourceResolver.java | 125 ------ .../web/servlet/view/FragmentsRendering.java | 37 -- .../web/servlet/config/MvcNamespaceTests.java | 5 +- .../DefaultEntityResponseBuilderTests.java | 3 +- .../DefaultServerResponseBuilderTests.java | 4 +- ...DeferredResultReturnValueHandlerTests.java | 26 -- .../WebJarsResourceResolverTests.java | 140 ------ .../client/AbstractWebSocketClient.java | 22 - .../web/socket/client/WebSocketClient.java | 35 -- .../config/WebSocketMessageBrokerStats.java | 34 +- .../messaging/WebSocketStompClient.java | 90 +--- .../client/AbstractClientSockJsSession.java | 11 - .../sockjs/client/AbstractXhrTransport.java | 9 - .../client/DefaultTransportRequest.java | 103 ----- .../web/socket/sockjs/client/Transport.java | 16 - .../client/WebSocketClientSockJsSession.java | 12 - .../sockjs/client/XhrClientSockJsSession.java | 21 - .../sockjs/client/XhrTransportTests.java | 4 +- 150 files changed, 141 insertions(+), 5922 deletions(-) delete mode 100644 spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncResultTests.java delete mode 100644 spring-core/src/main/java/org/springframework/core/task/AsyncListenableTaskExecutor.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/CompletableToListenableFutureAdapter.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureAdapter.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureTask.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/MonoToListenableFutureAdapter.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/SettableListenableFuture.java delete mode 100644 spring-core/src/main/java/org/springframework/util/concurrent/SuccessCallback.java delete mode 100644 spring-core/src/test/java/org/springframework/util/concurrent/ListenableFutureTaskTests.java delete mode 100644 spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java delete mode 100644 spring-core/src/test/java/org/springframework/util/concurrent/SettableListenableFutureTests.java delete mode 100644 spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/ListenableFutureReturnValueHandler.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequest.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpResponse.java delete mode 100644 spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequestFactory.java delete mode 100644 spring-web/src/main/java/org/springframework/web/filter/reactive/ServerHttpObservationFilter.java delete mode 100644 spring-web/src/main/java/org/springframework/web/service/invoker/HttpClientAdapter.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/BufferingClientHttpRequestFactoryWithOkHttpTests.java delete mode 100644 spring-web/src/test/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactoryTests.java delete mode 100644 spring-web/src/test/java/org/springframework/web/filter/reactive/ServerHttpObservationFilterTests.java delete mode 100644 spring-webflux/src/main/java/org/springframework/web/reactive/resource/WebJarsResourceResolver.java delete mode 100644 spring-webflux/src/test/java/org/springframework/web/reactive/resource/WebJarsResourceResolverTests.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/resource/WebJarsResourceResolver.java delete mode 100644 spring-webmvc/src/test/java/org/springframework/web/servlet/resource/WebJarsResourceResolverTests.java diff --git a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc index 15f15e7115d..c67851c129c 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/config.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/config.adoc @@ -647,13 +647,12 @@ For https://www.webjars.org/documentation[WebJars], versioned URLs like `/webjars/jquery/1.2.0/jquery.min.js` are the recommended and most efficient way to use them. The related resource location is configured out of the box with Spring Boot (or can be configured manually via `ResourceHandlerRegistry`) and does not require to add the -`org.webjars:webjars-locator-core` dependency. +`org.webjars:webjars-locator-lite` dependency. Version-less URLs like `/webjars/jquery/jquery.min.js` are supported through the `WebJarsResourceResolver` which is automatically registered when the -`org.webjars:webjars-locator-core` library is present on the classpath, at the cost of a -classpath scanning that could slow down application startup. The resolver can re-write URLs to -include the version of the jar and can also match against incoming URLs without versions +`org.webjars:webjars-locator-lite` library is present on the classpath. The resolver can re-write +URLs to include the version of the jar and can also match against incoming URLs without versions -- for example, from `/webjars/jquery/jquery.min.js` to `/webjars/jquery/1.2.0/jquery.min.js`. TIP: The Java configuration based on `ResourceHandlerRegistry` provides further options diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc index 362adf674df..87545bbadbd 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/static-resources.adoc @@ -48,13 +48,12 @@ For https://www.webjars.org/documentation[WebJars], versioned URLs like `/webjars/jquery/1.2.0/jquery.min.js` are the recommended and most efficient way to use them. The related resource location is configured out of the box with Spring Boot (or can be configured manually via `ResourceHandlerRegistry`) and does not require to add the -`org.webjars:webjars-locator-core` dependency. +`org.webjars:webjars-locator-lite` dependency. Version-less URLs like `/webjars/jquery/jquery.min.js` are supported through the `WebJarsResourceResolver` which is automatically registered when the -`org.webjars:webjars-locator-core` library is present on the classpath, at the cost of a -classpath scanning that could slow down application startup. The resolver can re-write URLs to -include the version of the jar and can also match against incoming URLs without versions +`org.webjars:webjars-locator-lite` library is present on the classpath. The resolver can re-write +URLs to include the version of the jar and can also match against incoming URLs without versions -- for example, from `/webjars/jquery/jquery.min.js` to `/webjars/jquery/1.2.0/jquery.min.js`. TIP: The Java configuration based on `ResourceHandlerRegistry` provides further options diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index 28d1cf7b611..4c5779824bd 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -38,7 +38,6 @@ dependencies { api("com.oracle.database.jdbc:ojdbc11:21.9.0.0") api("com.rometools:rome:1.19.0") api("com.squareup.okhttp3:mockwebserver:3.14.9") - api("com.squareup.okhttp3:okhttp:3.14.9") api("com.sun.activation:jakarta.activation:2.0.1") api("com.sun.xml.bind:jaxb-core:3.0.2") api("com.sun.xml.bind:jaxb-impl:3.0.2") @@ -142,7 +141,6 @@ dependencies { api("org.slf4j:slf4j-api:2.0.16") api("org.testng:testng:7.10.2") api("org.webjars:underscorejs:1.8.3") - api("org.webjars:webjars-locator-core:0.55") api("org.webjars:webjars-locator-lite:1.0.0") api("org.xmlunit:xmlunit-assertj:2.10.0") api("org.xmlunit:xmlunit-matchers:2.10.0") diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java index ea503479962..d9276cef976 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java @@ -281,15 +281,11 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { * @param returnType the declared return type (potentially a {@link Future} variant) * @return the execution result (potentially a corresponding {@link Future} handle) */ - @SuppressWarnings("removal") @Nullable protected Object doSubmit(Callable task, AsyncTaskExecutor executor, Class returnType) { if (CompletableFuture.class.isAssignableFrom(returnType)) { return executor.submitCompletable(task); } - else if (org.springframework.util.concurrent.ListenableFuture.class.isAssignableFrom(returnType)) { - return ((org.springframework.core.task.AsyncListenableTaskExecutor) executor).submitListenable(task); - } else if (Future.class.isAssignableFrom(returnType)) { return executor.submit(task); } diff --git a/spring-aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java b/spring-aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java index 6cf02e31db2..3b6877b2411 100644 --- a/spring-aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java +++ b/spring-aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java @@ -35,7 +35,6 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.ReflectionUtils; -import org.springframework.util.concurrent.ListenableFuture; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING; @@ -136,10 +135,7 @@ public class AnnotationAsyncExecutionAspectTests { assertThat(defaultThread.get()).isNotEqualTo(Thread.currentThread()); assertThat(defaultThread.get().getName()).doesNotStartWith("e1-"); - ListenableFuture e1Thread = obj.e1Work(); - assertThat(e1Thread.get().getName()).startsWith("e1-"); - - CompletableFuture e1OtherThread = obj.e1OtherWork(); + CompletableFuture e1OtherThread = obj.e1Work(); assertThat(e1OtherThread.get().getName()).startsWith("e1-"); } @@ -269,12 +265,7 @@ public class AnnotationAsyncExecutionAspectTests { } @Async("e1") - public ListenableFuture e1Work() { - return new AsyncResult<>(Thread.currentThread()); - } - - @Async("e1") - public CompletableFuture e1OtherWork() { + public CompletableFuture e1Work() { return CompletableFuture.completedFuture(Thread.currentThread()); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java index 4d6eecec4e3..89cbce16026 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java @@ -171,30 +171,6 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impl return new BeanInstanceSupplier<>(this.lookup, generator, null, this.shortcutBeanNames); } - /** - * Return a new {@link BeanInstanceSupplier} instance that uses the specified - * {@code generator} supplier to instantiate the underlying bean. - * @param generator a {@link ThrowingSupplier} to instantiate the underlying bean - * @return a new {@link BeanInstanceSupplier} instance with the specified generator - * @deprecated in favor of {@link #withGenerator(ThrowingFunction)} - */ - @Deprecated(since = "6.0.11", forRemoval = true) - public BeanInstanceSupplier withGenerator(ThrowingSupplier generator) { - Assert.notNull(generator, "'generator' must not be null"); - return new BeanInstanceSupplier<>(this.lookup, registeredBean -> generator.get(), - null, this.shortcutBeanNames); - } - - /** - * Return a new {@link BeanInstanceSupplier} instance - * that uses direct bean name injection shortcuts for specific parameters. - * @deprecated in favor of {@link #withShortcut(String...)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public BeanInstanceSupplier withShortcuts(String... beanNames) { - return withShortcut(beanNames); - } - /** * Return a new {@link BeanInstanceSupplier} instance that uses * direct bean name injection shortcuts for specific parameters. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java index aec5fadd4ab..1b54829f907 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java @@ -55,23 +55,6 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { return currentlyInvokedFactoryMethod.get(); } - /** - * Set the factory method currently being invoked or {@code null} to remove - * the current value, if any. - * @param method the factory method currently being invoked or {@code null} - * @since 6.0 - * @deprecated in favor of {@link #instantiateWithFactoryMethod(Method, Supplier)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public static void setCurrentlyInvokedFactoryMethod(@Nullable Method method) { - if (method != null) { - currentlyInvokedFactoryMethod.set(method); - } - else { - currentlyInvokedFactoryMethod.remove(); - } - } - /** * Invoke the given {@code instanceSupplier} with the factory method exposed * as being invoked. diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java index 078bbee216c..e64159e10f7 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java @@ -62,7 +62,6 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.function.ThrowingBiFunction; import org.springframework.util.function.ThrowingFunction; -import org.springframework.util.function.ThrowingSupplier; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -180,16 +179,6 @@ class BeanInstanceSupplierTests { .withMessage("'generator' must not be null"); } - @Test - @Deprecated - @SuppressWarnings("removal") - void withGeneratorWhenSupplierIsNullThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier.forConstructor(); - assertThatIllegalArgumentException() - .isThrownBy(() -> resolver.withGenerator((ThrowingSupplier) null)) - .withMessage("'generator' must not be null"); - } - @Test void getWithConstructorDoesNotSetResolvedFactoryMethod() { BeanInstanceSupplier resolver = BeanInstanceSupplier.forConstructor(String.class); @@ -236,18 +225,6 @@ class BeanInstanceSupplierTests { assertThat(resolver.get(registerBean)).isInstanceOf(String.class).isEqualTo("1"); } - @Test - @Deprecated - @SuppressWarnings("removal") - void getWithGeneratorCallsSupplier() { - BeanRegistrar registrar = new BeanRegistrar(SingleArgConstructor.class); - this.beanFactory.registerSingleton("one", "1"); - RegisteredBean registerBean = registrar.registerBean(this.beanFactory); - BeanInstanceSupplier resolver = BeanInstanceSupplier.forConstructor(String.class) - .withGenerator(() -> "1"); - assertThat(resolver.get(registerBean)).isInstanceOf(String.class).isEqualTo("1"); - } - @Test void getWhenRegisteredBeanIsNullThrowsException() { BeanInstanceSupplier resolver = BeanInstanceSupplier.forConstructor(String.class); diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SimpleThreadPoolTaskExecutor.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SimpleThreadPoolTaskExecutor.java index 9ab8c18cfa3..b728c7e7209 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SimpleThreadPoolTaskExecutor.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SimpleThreadPoolTaskExecutor.java @@ -25,12 +25,10 @@ import org.quartz.simpl.SimpleThreadPool; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.task.AsyncListenableTaskExecutor; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.scheduling.SchedulingException; import org.springframework.scheduling.SchedulingTaskExecutor; import org.springframework.util.Assert; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; /** * Subclass of Quartz's SimpleThreadPool that implements Spring's @@ -47,9 +45,9 @@ import org.springframework.util.concurrent.ListenableFutureTask; * @see org.springframework.core.task.TaskExecutor * @see SchedulerFactoryBean#setTaskExecutor */ -@SuppressWarnings({"deprecation", "removal"}) +@SuppressWarnings("deprecation") public class SimpleThreadPoolTaskExecutor extends SimpleThreadPool - implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, InitializingBean, DisposableBean { + implements AsyncTaskExecutor, SchedulingTaskExecutor, InitializingBean, DisposableBean { private boolean waitForJobsToCompleteOnShutdown = false; @@ -91,20 +89,6 @@ public class SimpleThreadPoolTaskExecutor extends SimpleThreadPool return future; } - @Override - public ListenableFuture submitListenable(Runnable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task, null); - execute(future); - return future; - } - - @Override - public ListenableFuture submitListenable(Callable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task); - execute(future); - return future; - } - @Override public void destroy() { diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index e1916d08657..58587849065 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -310,7 +310,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe return new Object[] {event}; } - @SuppressWarnings({"removal", "unchecked", "deprecation"}) protected void handleResult(Object result) { if (reactiveStreamsPresent && new ReactiveResultHandler().subscribeToPublisher(result)) { if (logger.isTraceEnabled()) { @@ -327,9 +326,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe } }); } - else if (result instanceof org.springframework.util.concurrent.ListenableFuture listenableFuture) { - listenableFuture.addCallback(this::publishEvents, this::handleAsyncError); - } else { publishEvents(result); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java index 3a7b5f0812c..f168677d087 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java @@ -22,10 +22,6 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.springframework.lang.Nullable; -import org.springframework.util.concurrent.FailureCallback; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; -import org.springframework.util.concurrent.SuccessCallback; /** * A pass-through {@code Future} handle that can be used for method signatures @@ -46,8 +42,7 @@ import org.springframework.util.concurrent.SuccessCallback; * @deprecated as of 6.0, in favor of {@link CompletableFuture} */ @Deprecated(since = "6.0") -@SuppressWarnings("removal") -public class AsyncResult implements ListenableFuture { +public class AsyncResult implements Future { @Nullable private final V value; @@ -105,38 +100,6 @@ public class AsyncResult implements ListenableFuture { return get(); } - @Override - public void addCallback(ListenableFutureCallback callback) { - addCallback(callback, callback); - } - - @Override - public void addCallback(SuccessCallback successCallback, FailureCallback failureCallback) { - try { - if (this.executionException != null) { - failureCallback.onFailure(exposedException(this.executionException)); - } - else { - successCallback.onSuccess(this.value); - } - } - catch (Throwable ex) { - // Ignore - } - } - - @Override - public CompletableFuture completable() { - if (this.executionException != null) { - CompletableFuture completable = new CompletableFuture<>(); - completable.completeExceptionally(exposedException(this.executionException)); - return completable; - } - else { - return CompletableFuture.completedFuture(this.value); - } - } - /** * Create a new async result which exposes the given value from {@link Future#get()}. @@ -144,7 +107,7 @@ public class AsyncResult implements ListenableFuture { * @since 4.2 * @see Future#get() */ - public static org.springframework.util.concurrent.ListenableFuture forValue(V value) { + public static Future forValue(V value) { return new AsyncResult<>(value, null); } @@ -156,7 +119,7 @@ public class AsyncResult implements ListenableFuture { * @since 4.2 * @see ExecutionException */ - public static org.springframework.util.concurrent.ListenableFuture forExecutionException(Throwable ex) { + public static Future forExecutionException(Throwable ex) { return new AsyncResult<>(null, ex); } diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java index d4a503d0c18..7bda93c2e95 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java @@ -26,14 +26,13 @@ import java.util.concurrent.Future; import jakarta.enterprise.concurrent.ManagedExecutors; import jakarta.enterprise.concurrent.ManagedTask; -import org.springframework.core.task.AsyncListenableTaskExecutor; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.TaskDecorator; import org.springframework.core.task.support.TaskExecutorAdapter; import org.springframework.lang.Nullable; import org.springframework.scheduling.SchedulingAwareRunnable; import org.springframework.scheduling.SchedulingTaskExecutor; import org.springframework.util.ClassUtils; -import org.springframework.util.concurrent.ListenableFuture; /** * Adapter that takes a {@code java.util.concurrent.Executor} and exposes @@ -62,8 +61,8 @@ import org.springframework.util.concurrent.ListenableFuture; * @see DefaultManagedTaskExecutor * @see ThreadPoolTaskExecutor */ -@SuppressWarnings({"deprecation", "removal"}) -public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, SchedulingTaskExecutor { +@SuppressWarnings("deprecation") +public class ConcurrentTaskExecutor implements AsyncTaskExecutor, SchedulingTaskExecutor { private static final Executor STUB_EXECUTOR = (task -> { throw new IllegalStateException("Executor not configured"); @@ -172,16 +171,6 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche return this.adaptedExecutor.submit(task); } - @Override - public ListenableFuture submitListenable(Runnable task) { - return this.adaptedExecutor.submitListenable(task); - } - - @Override - public ListenableFuture submitListenable(Callable task) { - return this.adaptedExecutor.submitListenable(task); - } - private TaskExecutorAdapter getAdaptedExecutor(Executor originalExecutor) { TaskExecutorAdapter adapter = @@ -224,16 +213,6 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche public Future submit(Callable task) { return super.submit(ManagedTaskBuilder.buildManagedTask(task, task.toString())); } - - @Override - public ListenableFuture submitListenable(Runnable task) { - return super.submitListenable(ManagedTaskBuilder.buildManagedTask(task, task.toString())); - } - - @Override - public ListenableFuture submitListenable(Callable task) { - return super.submitListenable(ManagedTaskBuilder.buildManagedTask(task, task.toString())); - } } diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java index f707d2bcc48..b004b0d5c3e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java @@ -218,18 +218,6 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T return super.submit(new DelegatingErrorHandlingCallable<>(task, this.errorHandler)); } - @SuppressWarnings({"deprecation", "removal"}) - @Override - public org.springframework.util.concurrent.ListenableFuture submitListenable(Runnable task) { - return super.submitListenable(TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, false)); - } - - @SuppressWarnings({"deprecation", "removal"}) - @Override - public org.springframework.util.concurrent.ListenableFuture submitListenable(Callable task) { - return super.submitListenable(new DelegatingErrorHandlingCallable<>(task, this.errorHandler)); - } - @Override @Nullable public ScheduledFuture schedule(Runnable task, Trigger trigger) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java index bb66d4512f1..ebba6105994 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java @@ -269,18 +269,6 @@ public class SimpleAsyncTaskScheduler extends SimpleAsyncTaskExecutor implements return super.submit(new DelegatingErrorHandlingCallable<>(task, this.errorHandler)); } - @SuppressWarnings({"deprecation", "removal"}) - @Override - public org.springframework.util.concurrent.ListenableFuture submitListenable(Runnable task) { - return super.submitListenable(TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, false)); - } - - @SuppressWarnings({"deprecation", "removal"}) - @Override - public org.springframework.util.concurrent.ListenableFuture submitListenable(Callable task) { - return super.submitListenable(new DelegatingErrorHandlingCallable<>(task, this.errorHandler)); - } - @Override @Nullable public ScheduledFuture schedule(Runnable task, Trigger trigger) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java index 66e54c8fd60..9451b64839b 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.java @@ -30,15 +30,13 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import org.springframework.core.task.AsyncListenableTaskExecutor; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.TaskDecorator; import org.springframework.core.task.TaskRejectedException; import org.springframework.lang.Nullable; import org.springframework.scheduling.SchedulingTaskExecutor; import org.springframework.util.Assert; import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; /** * JavaBean that allows for configuring a {@link java.util.concurrent.ThreadPoolExecutor} @@ -80,9 +78,9 @@ import org.springframework.util.concurrent.ListenableFutureTask; * @see ThreadPoolExecutorFactoryBean * @see ConcurrentTaskExecutor */ -@SuppressWarnings({"serial", "deprecation", "removal"}) +@SuppressWarnings({"serial", "deprecation"}) public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport - implements AsyncListenableTaskExecutor, SchedulingTaskExecutor { + implements AsyncTaskExecutor, SchedulingTaskExecutor { private final Object poolSizeMonitor = new Object(); @@ -414,32 +412,6 @@ public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport } } - @Override - public ListenableFuture submitListenable(Runnable task) { - ExecutorService executor = getThreadPoolExecutor(); - try { - ListenableFutureTask future = new ListenableFutureTask<>(task, null); - executor.execute(future); - return future; - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException(executor, task, ex); - } - } - - @Override - public ListenableFuture submitListenable(Callable task) { - ExecutorService executor = getThreadPoolExecutor(); - try { - ListenableFutureTask future = new ListenableFutureTask<>(task); - executor.execute(future); - return future; - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException(executor, task, ex); - } - } - @Override protected void cancelRemainingTask(Runnable task) { super.cancelRemainingTask(task); diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java index 458af46ae74..581e1d48520 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java @@ -19,7 +19,6 @@ package org.springframework.scheduling.concurrent; import java.time.Clock; import java.time.Duration; import java.time.Instant; -import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Delayed; import java.util.concurrent.ExecutionException; @@ -36,7 +35,7 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.springframework.core.task.AsyncListenableTaskExecutor; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.TaskDecorator; import org.springframework.core.task.TaskRejectedException; import org.springframework.lang.Nullable; @@ -45,10 +44,7 @@ import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.support.TaskUtils; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ErrorHandler; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; /** * A standard implementation of Spring's {@link TaskScheduler} interface, wrapping @@ -74,9 +70,9 @@ import org.springframework.util.concurrent.ListenableFutureTask; * @see ThreadPoolTaskExecutor * @see SimpleAsyncTaskScheduler */ -@SuppressWarnings({"serial", "deprecation", "removal"}) +@SuppressWarnings({"serial", "deprecation"}) public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport - implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, TaskScheduler { + implements AsyncTaskExecutor, SchedulingTaskExecutor, TaskScheduler { private static final TimeUnit NANO = TimeUnit.NANOSECONDS; @@ -100,10 +96,6 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport @Nullable private ScheduledExecutorService scheduledExecutor; - // Underlying ScheduledFutureTask to user-level ListenableFuture handle, if any - private final Map> listenableFutureMap = - new ConcurrentReferenceHashMap<>(16, ConcurrentReferenceHashMap.ReferenceType.WEAK); - /** * Set the ScheduledExecutorService's pool size. @@ -357,49 +349,6 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport } } - @Override - public ListenableFuture submitListenable(Runnable task) { - ExecutorService executor = getScheduledExecutor(); - try { - ListenableFutureTask listenableFuture = new ListenableFutureTask<>(task, null); - executeAndTrack(executor, listenableFuture); - return listenableFuture; - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException(executor, task, ex); - } - } - - @Override - public ListenableFuture submitListenable(Callable task) { - ExecutorService executor = getScheduledExecutor(); - try { - ListenableFutureTask listenableFuture = new ListenableFutureTask<>(task); - executeAndTrack(executor, listenableFuture); - return listenableFuture; - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException(executor, task, ex); - } - } - - private void executeAndTrack(ExecutorService executor, ListenableFutureTask listenableFuture) { - Future scheduledFuture = executor.submit(errorHandlingTask(listenableFuture, false)); - this.listenableFutureMap.put(scheduledFuture, listenableFuture); - listenableFuture.addCallback(result -> this.listenableFutureMap.remove(scheduledFuture), - ex -> this.listenableFutureMap.remove(scheduledFuture)); - } - - @Override - protected void cancelRemainingTask(Runnable task) { - super.cancelRemainingTask(task); - // Cancel associated user-level ListenableFuture handle as well - ListenableFuture listenableFuture = this.listenableFutureMap.get(task); - if (listenableFuture != null) { - listenableFuture.cancel(true); - } - } - // TaskScheduler implementation diff --git a/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java b/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java index 69ff06f55c2..fccb5ad41ca 100644 --- a/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java +++ b/spring-context/src/main/java/org/springframework/validation/method/MethodValidationResult.java @@ -81,19 +81,6 @@ public interface MethodValidationResult { */ List getParameterValidationResults(); - /** - * Return all validation results. This includes both method parameters with - * errors directly on them, and Object method parameters with nested errors - * on their fields and properties. - * @see #getValueResults() - * @see #getBeanResults() - * @deprecated deprecated in favor of {@link #getParameterValidationResults()} - */ - @Deprecated(since = "6.2", forRemoval = true) - default List getAllValidationResults() { - return getParameterValidationResults(); - } - /** * Return the subset of {@link #getParameterValidationResults() allValidationResults} * that includes method parameters with validation errors directly on method diff --git a/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java b/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java index 128b078d33c..740796976d0 100644 --- a/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java +++ b/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java @@ -85,35 +85,6 @@ public class ParameterValidationResult { this.sourceLookup = sourceLookup; } - /** - * Create a {@code ParameterValidationResult}. - * @deprecated in favor of - * {@link ParameterValidationResult#ParameterValidationResult(MethodParameter, Object, Collection, Object, Integer, Object, BiFunction)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public ParameterValidationResult( - MethodParameter param, @Nullable Object arg, Collection errors, - @Nullable Object container, @Nullable Integer index, @Nullable Object key) { - - this(param, arg, errors, container, index, key, (error, sourceType) -> { - throw new IllegalArgumentException("No source object of the given type"); - }); - } - - /** - * Create a {@code ParameterValidationResult}. - * @deprecated in favor of - * {@link ParameterValidationResult#ParameterValidationResult(MethodParameter, Object, Collection, Object, Integer, Object, BiFunction)} - */ - @Deprecated(since = "6.1.3", forRemoval = true) - public ParameterValidationResult( - MethodParameter param, @Nullable Object arg, Collection errors) { - - this(param, arg, errors, null, null, null, (error, sourceType) -> { - throw new IllegalArgumentException("No source object of the given type"); - }); - } - /** * The method parameter the validation results are for. diff --git a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java index ac511516963..5578213184e 100644 --- a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java +++ b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java @@ -279,25 +279,6 @@ class AnnotationDrivenEventListenerTests { this.eventCollector.assertTotalEventsCount(2); } - @Test - @SuppressWarnings({"deprecation", "removal"}) - void listenableFutureReply() { - load(TestEventListener.class, ReplyEventListener.class); - org.springframework.util.concurrent.SettableListenableFuture future = - new org.springframework.util.concurrent.SettableListenableFuture<>(); - future.set("dummy"); - AnotherTestEvent event = new AnotherTestEvent(this, future); - ReplyEventListener replyEventListener = this.context.getBean(ReplyEventListener.class); - TestEventListener listener = this.context.getBean(TestEventListener.class); - - this.eventCollector.assertNoEventReceived(listener); - this.eventCollector.assertNoEventReceived(replyEventListener); - this.context.publishEvent(event); - this.eventCollector.assertEvent(replyEventListener, event); - this.eventCollector.assertEvent(listener, "dummy"); // reply - this.eventCollector.assertTotalEventsCount(2); - } - @Test void completableFutureReply() { load(TestEventListener.class, ReplyEventListener.class); diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessorTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessorTests.java index 3d73ac0bea8..42d5851eec2 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessorTests.java @@ -200,20 +200,6 @@ class AsyncAnnotationBeanPostProcessorTests { assertFutureWithException(result, exceptionHandler); } - @Test - @SuppressWarnings("resource") - public void handleExceptionWithListenableFuture() { - ConfigurableApplicationContext context = - new AnnotationConfigApplicationContext(ConfigWithExceptionHandler.class); - ITestBean testBean = context.getBean("target", ITestBean.class); - - TestableAsyncUncaughtExceptionHandler exceptionHandler = - context.getBean("exceptionHandler", TestableAsyncUncaughtExceptionHandler.class); - assertThat(exceptionHandler.isCalled()).as("handler should not have been called yet").isFalse(); - Future result = testBean.failWithListenableFuture(); - assertFutureWithException(result, exceptionHandler); - } - private void assertFutureWithException(Future result, TestableAsyncUncaughtExceptionHandler exceptionHandler) { assertThatExceptionOfType(ExecutionException.class).isThrownBy( @@ -275,9 +261,6 @@ class AsyncAnnotationBeanPostProcessorTests { Future failWithFuture(); - @SuppressWarnings({"deprecation", "removal"}) - org.springframework.util.concurrent.ListenableFuture failWithListenableFuture(); - void failWithVoid(); void await(long timeout); @@ -308,13 +291,6 @@ class AsyncAnnotationBeanPostProcessorTests { throw new UnsupportedOperationException("failWithFuture"); } - @Async - @Override - @SuppressWarnings({"deprecation", "removal"}) - public org.springframework.util.concurrent.ListenableFuture failWithListenableFuture() { - throw new UnsupportedOperationException("failWithListenableFuture"); - } - @Async @Override public void failWithVoid() { diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java index 5be5a1214b5..c64a14d14ad 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java @@ -42,7 +42,6 @@ import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.support.GenericApplicationContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.util.concurrent.ListenableFuture; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -51,7 +50,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; * @author Juergen Hoeller * @author Chris Beams */ -@SuppressWarnings({"resource", "deprecation", "removal"}) class AsyncExecutionTests { private static String originalThreadName; @@ -81,8 +79,6 @@ class AsyncExecutionTests { asyncTest.doSomething(10); Future future = asyncTest.returnSomething(20); assertThat(future.get()).isEqualTo("20"); - ListenableFuture listenableFuture = asyncTest.returnSomethingListenable(20); - assertThat(listenableFuture.get()).isEqualTo("20"); CompletableFuture completableFuture = asyncTest.returnSomethingCompletable(20); assertThat(completableFuture.get()).isEqualTo("20"); @@ -94,14 +90,6 @@ class AsyncExecutionTests { asyncTest.returnSomething(-1).get()) .withCauseInstanceOf(IOException.class); - assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> - asyncTest.returnSomethingListenable(0).get()) - .withCauseInstanceOf(IllegalArgumentException.class); - - assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> - asyncTest.returnSomethingListenable(-1).get()) - .withCauseInstanceOf(IOException.class); - assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> asyncTest.returnSomethingCompletable(0).get()) .withCauseInstanceOf(IllegalArgumentException.class); @@ -174,8 +162,6 @@ class AsyncExecutionTests { asyncTest.doSomething(10); Future future = asyncTest.returnSomething(20); assertThat(future.get()).isEqualTo("20"); - ListenableFuture listenableFuture = asyncTest.returnSomethingListenable(20); - assertThat(listenableFuture.get()).isEqualTo("20"); CompletableFuture completableFuture = asyncTest.returnSomethingCompletable(20); assertThat(completableFuture.get()).isEqualTo("20"); @@ -183,10 +169,6 @@ class AsyncExecutionTests { asyncTest.returnSomething(0).get()) .withCauseInstanceOf(IllegalArgumentException.class); - assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> - asyncTest.returnSomethingListenable(0).get()) - .withCauseInstanceOf(IllegalArgumentException.class); - assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> asyncTest.returnSomethingCompletable(0).get()) .withCauseInstanceOf(IllegalArgumentException.class); @@ -419,18 +401,6 @@ class AsyncExecutionTests { return AsyncResult.forValue(Integer.toString(i)); } - @Async - public ListenableFuture returnSomethingListenable(int i) { - assertThat(Thread.currentThread().getName()).isNotEqualTo(originalThreadName); - if (i == 0) { - throw new IllegalArgumentException(); - } - else if (i < 0) { - return AsyncResult.forExecutionException(new IOException()); - } - return new AsyncResult<>(Integer.toString(i)); - } - @Async public CompletableFuture returnSomethingCompletable(int i) { assertThat(Thread.currentThread().getName()).isNotEqualTo(originalThreadName); @@ -505,14 +475,6 @@ class AsyncExecutionTests { return new AsyncResult<>(Integer.toString(i)); } - public ListenableFuture returnSomethingListenable(int i) { - assertThat(Thread.currentThread().getName()).isNotEqualTo(originalThreadName); - if (i == 0) { - throw new IllegalArgumentException(); - } - return new AsyncResult<>(Integer.toString(i)); - } - @Async public CompletableFuture returnSomethingCompletable(int i) { assertThat(Thread.currentThread().getName()).isNotEqualTo(originalThreadName); diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncResultTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncResultTests.java deleted file mode 100644 index b4ac333da9c..00000000000 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/AsyncResultTests.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.annotation; - -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.ExecutionException; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * @author Juergen Hoeller - */ -class AsyncResultTests { - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - public void asyncResultWithCallbackAndValue() throws Exception { - String value = "val"; - final Set values = new HashSet<>(1); - org.springframework.util.concurrent.ListenableFuture future = AsyncResult.forValue(value); - future.addCallback(new org.springframework.util.concurrent.ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - values.add(result); - } - @Override - public void onFailure(Throwable ex) { - throw new AssertionError("Failure callback not expected: " + ex, ex); - } - }); - assertThat(values).singleElement().isSameAs(value); - assertThat(future.get()).isSameAs(value); - assertThat(future.completable().get()).isSameAs(value); - future.completable().thenAccept(v -> assertThat(v).isSameAs(value)); - } - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - public void asyncResultWithCallbackAndException() { - IOException ex = new IOException(); - final Set values = new HashSet<>(1); - org.springframework.util.concurrent.ListenableFuture future = AsyncResult.forExecutionException(ex); - future.addCallback(new org.springframework.util.concurrent.ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - throw new AssertionError("Success callback not expected: " + result); - } - @Override - public void onFailure(Throwable ex) { - values.add(ex); - } - }); - assertThat(values).singleElement().isSameAs(ex); - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(future::get) - .withCause(ex); - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(future.completable()::get) - .withCause(ex); - } - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - public void asyncResultWithSeparateCallbacksAndValue() throws Exception { - String value = "val"; - final Set values = new HashSet<>(1); - org.springframework.util.concurrent.ListenableFuture future = AsyncResult.forValue(value); - future.addCallback(values::add, ex -> new AssertionError("Failure callback not expected: " + ex)); - assertThat(values).singleElement().isSameAs(value); - assertThat(future.get()).isSameAs(value); - assertThat(future.completable().get()).isSameAs(value); - future.completable().thenAccept(v -> assertThat(v).isSameAs(value)); - } - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - public void asyncResultWithSeparateCallbacksAndException() { - IOException ex = new IOException(); - final Set values = new HashSet<>(1); - org.springframework.util.concurrent.ListenableFuture future = AsyncResult.forExecutionException(ex); - future.addCallback(result -> new AssertionError("Success callback not expected: " + result), values::add); - assertThat(values).singleElement().isSameAs(ex); - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(future::get) - .withCause(ex); - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(future.completable()::get) - .withCause(ex); - } - -} diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/AbstractSchedulingTaskExecutorTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/AbstractSchedulingTaskExecutorTests.java index e6c01beaaa1..4e7fc7c470b 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/AbstractSchedulingTaskExecutorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/AbstractSchedulingTaskExecutorTests.java @@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; import org.springframework.beans.factory.DisposableBean; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.lang.Nullable; import static org.assertj.core.api.Assertions.assertThat; @@ -47,8 +48,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; */ abstract class AbstractSchedulingTaskExecutorTests { - @SuppressWarnings("removal") - private org.springframework.core.task.AsyncListenableTaskExecutor executor; + private AsyncTaskExecutor executor; protected String testName; @@ -64,8 +64,7 @@ abstract class AbstractSchedulingTaskExecutorTests { this.executor = buildExecutor(); } - @SuppressWarnings("removal") - protected abstract org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor(); + protected abstract AsyncTaskExecutor buildExecutor(); @AfterEach void shutdownExecutor() throws Exception { @@ -124,22 +123,6 @@ abstract class AbstractSchedulingTaskExecutorTests { }); } - @Test - @SuppressWarnings({ "deprecation", "removal" }) - void submitListenableRunnable() { - TestTask task = new TestTask(this.testName, 1); - // Act - org.springframework.util.concurrent.ListenableFuture future = executor.submitListenable(task); - future.addCallback(result -> outcome = result, ex -> outcome = ex); - // Assert - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .until(future::isDone); - assertThat(outcome).isNull(); - assertThreadNamePrefix(task); - } - @Test void submitCompletableRunnable() { TestTask task = new TestTask(this.testName, 1); @@ -155,21 +138,6 @@ abstract class AbstractSchedulingTaskExecutorTests { assertThreadNamePrefix(task); } - @Test - @SuppressWarnings({ "deprecation", "removal" }) - void submitFailingListenableRunnable() { - TestTask task = new TestTask(this.testName, 0); - org.springframework.util.concurrent.ListenableFuture future = executor.submitListenable(task); - future.addCallback(result -> outcome = result, ex -> outcome = ex); - - Awaitility.await() - .dontCatchUncaughtExceptions() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .until(() -> future.isDone() && outcome != null); - assertThat(outcome.getClass()).isSameAs(RuntimeException.class); - } - @Test void submitFailingCompletableRunnable() { TestTask task = new TestTask(this.testName, 0); @@ -184,43 +152,15 @@ abstract class AbstractSchedulingTaskExecutorTests { assertThat(outcome.getClass()).isSameAs(CompletionException.class); } - @Test - @SuppressWarnings({ "deprecation", "removal" }) - void submitListenableRunnableWithGetAfterShutdown() throws Exception { - org.springframework.util.concurrent.ListenableFuture future1 = executor.submitListenable(new TestTask(this.testName, -1)); - org.springframework.util.concurrent.ListenableFuture future2 = executor.submitListenable(new TestTask(this.testName, -1)); - shutdownExecutor(); - - try { - future1.get(1000, TimeUnit.MILLISECONDS); - } - catch (Exception ex) { - // ignore - } - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .untilAsserted(() -> assertThatExceptionOfType(CancellationException.class) - .isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS))); - } - @Test void submitCompletableRunnableWithGetAfterShutdown() throws Exception { CompletableFuture future1 = executor.submitCompletable(new TestTask(this.testName, -1)); CompletableFuture future2 = executor.submitCompletable(new TestTask(this.testName, -1)); shutdownExecutor(); - - try { + assertThatExceptionOfType(TimeoutException.class).isThrownBy(() -> { future1.get(1000, TimeUnit.MILLISECONDS); - } - catch (Exception ex) { - // ignore - } - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .untilAsserted(() -> assertThatExceptionOfType(TimeoutException.class) - .isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS))); + future2.get(1000, TimeUnit.MILLISECONDS); + }); } @Test @@ -245,57 +185,6 @@ abstract class AbstractSchedulingTaskExecutorTests { Future future1 = executor.submit(new TestCallable(this.testName, -1)); Future future2 = executor.submit(new TestCallable(this.testName, -1)); shutdownExecutor(); - - try { - future1.get(1000, TimeUnit.MILLISECONDS); - } - catch (Exception ex) { - // ignore - } - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .untilAsserted(() -> assertThatExceptionOfType(CancellationException.class) - .isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS))); - } - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - void submitListenableCallable() { - TestCallable task = new TestCallable(this.testName, 1); - // Act - org.springframework.util.concurrent.ListenableFuture future = executor.submitListenable(task); - future.addCallback(result -> outcome = result, ex -> outcome = ex); - // Assert - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .until(() -> future.isDone() && outcome != null); - assertThat(outcome.toString().substring(0, this.threadNamePrefix.length())).isEqualTo(this.threadNamePrefix); - } - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - void submitFailingListenableCallable() { - TestCallable task = new TestCallable(this.testName, 0); - // Act - org.springframework.util.concurrent.ListenableFuture future = executor.submitListenable(task); - future.addCallback(result -> outcome = result, ex -> outcome = ex); - // Assert - Awaitility.await() - .dontCatchUncaughtExceptions() - .atMost(5, TimeUnit.SECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .until(() -> future.isDone() && outcome != null); - assertThat(outcome.getClass()).isSameAs(RuntimeException.class); - } - - @Test - @SuppressWarnings({ "deprecation", "removal" }) - void submitListenableCallableWithGetAfterShutdown() throws Exception { - org.springframework.util.concurrent.ListenableFuture future1 = executor.submitListenable(new TestCallable(this.testName, -1)); - org.springframework.util.concurrent.ListenableFuture future2 = executor.submitListenable(new TestCallable(this.testName, -1)); - shutdownExecutor(); assertThatExceptionOfType(CancellationException.class).isThrownBy(() -> { future1.get(1000, TimeUnit.MILLISECONDS); future2.get(1000, TimeUnit.MILLISECONDS); diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutorTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutorTests.java index b1357b12178..ab37b9ca949 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutorTests.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.NoOpRunnable; import org.springframework.core.task.TaskDecorator; import org.springframework.util.Assert; @@ -42,8 +43,7 @@ class ConcurrentTaskExecutorTests extends AbstractSchedulingTaskExecutorTests { @Override - @SuppressWarnings("removal") - protected org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor() { + protected AsyncTaskExecutor buildExecutor() { concurrentExecutor.setThreadFactory(new CustomizableThreadFactory(this.threadNamePrefix)); return new ConcurrentTaskExecutor(concurrentExecutor); } diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskSchedulerTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskSchedulerTests.java index 11711fbc719..e2380969f63 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskSchedulerTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ConcurrentTaskSchedulerTests.java @@ -31,6 +31,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.util.ErrorHandler; @@ -52,8 +53,7 @@ class ConcurrentTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests { @Override - @SuppressWarnings("removal") - protected org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor() { + protected AsyncTaskExecutor buildExecutor() { threadFactory.setThreadNamePrefix(this.threadNamePrefix); scheduler.setTaskDecorator(runnable -> () -> { taskRun.set(true); @@ -79,26 +79,12 @@ class ConcurrentTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests { // decorated Future cannot be cancelled on shutdown with ConcurrentTaskScheduler (see above) } - @Test - @SuppressWarnings("deprecation") - @Override - void submitListenableRunnableWithGetAfterShutdown() { - // decorated Future cannot be cancelled on shutdown with ConcurrentTaskScheduler (see above) - } - @Test @Override void submitCallableWithGetAfterShutdown() { // decorated Future cannot be cancelled on shutdown with ConcurrentTaskScheduler (see above) } - @Test - @SuppressWarnings("deprecation") - @Override - void submitListenableCallableWithGetAfterShutdown() { - // decorated Future cannot be cancelled on shutdown with ConcurrentTaskScheduler (see above) - } - @Test void executeFailingRunnableWithErrorHandler() { diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/DecoratedThreadPoolTaskExecutorTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/DecoratedThreadPoolTaskExecutorTests.java index d69ac85a642..abd600226ab 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/DecoratedThreadPoolTaskExecutorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/DecoratedThreadPoolTaskExecutorTests.java @@ -16,6 +16,7 @@ package org.springframework.scheduling.concurrent; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable; import org.springframework.scheduling.support.TaskUtils; @@ -26,8 +27,7 @@ import org.springframework.scheduling.support.TaskUtils; class DecoratedThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests { @Override - @SuppressWarnings("removal") - protected org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor() { + protected AsyncTaskExecutor buildExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setTaskDecorator(runnable -> new DelegatingErrorHandlingRunnable(runnable, TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER)); diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskSchedulerTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskSchedulerTests.java index b3cd12d52e3..7bcab783358 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskSchedulerTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskSchedulerTests.java @@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.util.ErrorHandler; @@ -45,8 +46,7 @@ class SimpleAsyncTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests @Override - @SuppressWarnings("removal") - protected org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor() { + protected AsyncTaskExecutor buildExecutor() { scheduler.setTaskDecorator(runnable -> () -> { taskRun.set(true); runnable.run(); @@ -62,12 +62,6 @@ class SimpleAsyncTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests // decorated Future cannot be cancelled on shutdown with SimpleAsyncTaskScheduler } - @Test - @Override - void submitListenableRunnableWithGetAfterShutdown() { - // decorated Future cannot be cancelled on shutdown with SimpleAsyncTaskScheduler - } - @Test @Override void submitCompletableRunnableWithGetAfterShutdown() { @@ -80,13 +74,6 @@ class SimpleAsyncTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests // decorated Future cannot be cancelled on shutdown with SimpleAsyncTaskScheduler } - @Test - @SuppressWarnings("deprecation") - @Override - void submitListenableCallableWithGetAfterShutdown() { - // decorated Future cannot be cancelled on shutdown with SimpleAsyncTaskScheduler - } - @Test @Override void submitCompletableCallableWithGetAfterShutdown() { diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutorTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutorTests.java index 5201af2a34c..35a62f44b33 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutorTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutorTests.java @@ -23,6 +23,8 @@ import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; +import org.springframework.core.task.AsyncTaskExecutor; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -41,8 +43,7 @@ class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests { @Override - @SuppressWarnings("removal") - protected org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor() { + protected AsyncTaskExecutor buildExecutor() { executor.setThreadNamePrefix(this.threadNamePrefix); executor.setMaxPoolSize(1); executor.afterPropertiesSet(); diff --git a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java index 63cbeafbcb2..712d69ba5a6 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java @@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.util.ErrorHandler; @@ -49,8 +50,7 @@ class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests { @Override - @SuppressWarnings("removal") - protected org.springframework.core.task.AsyncListenableTaskExecutor buildExecutor() { + protected AsyncTaskExecutor buildExecutor() { scheduler.setTaskDecorator(runnable -> () -> { taskRun.set(true); runnable.run(); diff --git a/spring-core/src/main/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrar.java b/spring-core/src/main/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrar.java index f5e3525a1e8..22119ee762e 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrar.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,9 +35,10 @@ import org.springframework.util.ResourceUtils; * * @author Stephane Nicoll * @author Sam Brannen + * @author Juergen Hoeller * @since 6.0 */ -public class FilePatternResourceHintsRegistrar { +public final class FilePatternResourceHintsRegistrar { private final List classpathLocations; @@ -46,26 +47,16 @@ public class FilePatternResourceHintsRegistrar { private final List fileExtensions; - /** - * Create a new instance for the specified file prefixes, classpath locations, - * and file extensions. - * @param filePrefixes the file prefixes - * @param classpathLocations the classpath locations - * @param fileExtensions the file extensions (starting with a dot) - * @deprecated as of 6.0.12 in favor of {@linkplain #forClassPathLocations(String...) the builder} - */ - @Deprecated(since = "6.0.12", forRemoval = true) - public FilePatternResourceHintsRegistrar(List filePrefixes, List classpathLocations, + private FilePatternResourceHintsRegistrar(List filePrefixes, List classpathLocations, List fileExtensions) { - this.classpathLocations = validateClasspathLocations(classpathLocations); + this.classpathLocations = validateClassPathLocations(classpathLocations); this.filePrefixes = validateFilePrefixes(filePrefixes); this.fileExtensions = validateFileExtensions(fileExtensions); } - @Deprecated(since = "6.0.12", forRemoval = true) - public void registerHints(ResourceHints hints, @Nullable ClassLoader classLoader) { + private void registerHints(ResourceHints hints, @Nullable ClassLoader classLoader) { ClassLoader classLoaderToUse = (classLoader != null ? classLoader : getClass().getClassLoader()); List includes = new ArrayList<>(); for (String location : this.classpathLocations) { @@ -85,7 +76,7 @@ public class FilePatternResourceHintsRegistrar { /** * Configure the registrar with the specified - * {@linkplain Builder#withClasspathLocations(String...) classpath locations}. + * {@linkplain Builder#withClassPathLocations(String...) classpath locations}. * @param classpathLocations the classpath locations * @return a {@link Builder} to further configure the registrar * @since 6.0.12 @@ -97,17 +88,17 @@ public class FilePatternResourceHintsRegistrar { /** * Configure the registrar with the specified - * {@linkplain Builder#withClasspathLocations(List) classpath locations}. + * {@linkplain Builder#withClassPathLocations(List) classpath locations}. * @param classpathLocations the classpath locations * @return a {@link Builder} to further configure the registrar * @since 6.0.12 * @see #forClassPathLocations(String...) */ public static Builder forClassPathLocations(List classpathLocations) { - return new Builder().withClasspathLocations(classpathLocations); + return new Builder().withClassPathLocations(classpathLocations); } - private static List validateClasspathLocations(List classpathLocations) { + private static List validateClassPathLocations(List classpathLocations) { Assert.notEmpty(classpathLocations, "At least one classpath location must be specified"); List parsedLocations = new ArrayList<>(); for (String location : classpathLocations) { @@ -162,15 +153,20 @@ public class FilePatternResourceHintsRegistrar { /** * Consider the specified classpath locations. - *

A location can either be a special {@value ResourceUtils#CLASSPATH_URL_PREFIX} - * pseudo location or a standard location, such as {@code com/example/resources}. - * An empty String represents the root of the classpath. - * @param classpathLocations the classpath locations to consider - * @return this builder - * @see #withClasspathLocations(List) + * @deprecated in favor of {@link #withClassPathLocations(String...)} */ + @Deprecated(since = "7.0", forRemoval = true) public Builder withClasspathLocations(String... classpathLocations) { - return withClasspathLocations(Arrays.asList(classpathLocations)); + return withClassPathLocations(Arrays.asList(classpathLocations)); + } + + /** + * Consider the specified classpath locations. + * @deprecated in favor of {@link #withClassPathLocations(List)} + */ + @Deprecated(since = "7.0", forRemoval = true) + public Builder withClasspathLocations(List classpathLocations) { + return withClassPathLocations(classpathLocations); } /** @@ -180,10 +176,25 @@ public class FilePatternResourceHintsRegistrar { * An empty String represents the root of the classpath. * @param classpathLocations the classpath locations to consider * @return this builder - * @see #withClasspathLocations(String...) + * @since 7.0 + * @see #withClassPathLocations(List) */ - public Builder withClasspathLocations(List classpathLocations) { - this.classpathLocations.addAll(validateClasspathLocations(classpathLocations)); + public Builder withClassPathLocations(String... classpathLocations) { + return withClassPathLocations(Arrays.asList(classpathLocations)); + } + + /** + * Consider the specified classpath locations. + *

A location can either be a special {@value ResourceUtils#CLASSPATH_URL_PREFIX} + * pseudo location or a standard location, such as {@code com/example/resources}. + * An empty String represents the root of the classpath. + * @param classpathLocations the classpath locations to consider + * @return this builder + * @since 7.0 + * @see #withClassPathLocations(String...) + */ + public Builder withClassPathLocations(List classpathLocations) { + this.classpathLocations.addAll(validateClassPathLocations(classpathLocations)); return this; } @@ -235,7 +246,6 @@ public class FilePatternResourceHintsRegistrar { return this; } - private FilePatternResourceHintsRegistrar build() { return new FilePatternResourceHintsRegistrar(this.filePrefixes, this.classpathLocations, this.fileExtensions); diff --git a/spring-core/src/main/java/org/springframework/core/task/AsyncListenableTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/AsyncListenableTaskExecutor.java deleted file mode 100644 index a89a7efd126..00000000000 --- a/spring-core/src/main/java/org/springframework/core/task/AsyncListenableTaskExecutor.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.task; - -import java.util.concurrent.Callable; - -/** - * Extension of the {@link AsyncTaskExecutor} interface, adding the capability to submit - * tasks for {@code ListenableFutures}. - * - * @author Arjen Poutsma - * @since 4.0 - * @deprecated as of 6.0, in favor of - * {@link AsyncTaskExecutor#submitCompletable(Runnable)} and - * {@link AsyncTaskExecutor#submitCompletable(Callable)} - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public interface AsyncListenableTaskExecutor extends AsyncTaskExecutor { - - /** - * Submit a {@code Runnable} task for execution, receiving a {@code ListenableFuture} - * representing that task. The Future will return a {@code null} result upon completion. - * @param task the {@code Runnable} to execute (never {@code null}) - * @return a {@code ListenableFuture} representing pending completion of the task - * @throws TaskRejectedException if the given task was not accepted - * @deprecated in favor of {@link AsyncTaskExecutor#submitCompletable(Runnable)} - */ - @Deprecated(since = "6.0", forRemoval = true) - org.springframework.util.concurrent.ListenableFuture submitListenable(Runnable task); - - /** - * Submit a {@code Callable} task for execution, receiving a {@code ListenableFuture} - * representing that task. The Future will return the Callable's result upon - * completion. - * @param task the {@code Callable} to execute (never {@code null}) - * @return a {@code ListenableFuture} representing pending completion of the task - * @throws TaskRejectedException if the given task was not accepted - * @deprecated in favor of {@link AsyncTaskExecutor#submitCompletable(Callable)} - */ - @Deprecated(since = "6.0", forRemoval = true) - org.springframework.util.concurrent.ListenableFuture submitListenable(Callable task); - -} diff --git a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java index e2d2363373f..413a80367d1 100644 --- a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java +++ b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java @@ -28,8 +28,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrencyThrottleSupport; import org.springframework.util.CustomizableThreadCreator; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; /** * {@link TaskExecutor} implementation that fires up a new Thread for each task, @@ -58,9 +56,9 @@ import org.springframework.util.concurrent.ListenableFutureTask; * @see org.springframework.scheduling.concurrent.SimpleAsyncTaskScheduler * @see org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor */ -@SuppressWarnings({"serial", "removal"}) +@SuppressWarnings("serial") public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator - implements AsyncListenableTaskExecutor, Serializable, AutoCloseable { + implements AsyncTaskExecutor, Serializable, AutoCloseable { /** * Permit any number of concurrent invocations: that is, don't throttle concurrency. @@ -294,22 +292,6 @@ public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator return future; } - @SuppressWarnings("deprecation") - @Override - public ListenableFuture submitListenable(Runnable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task, null); - execute(future, TIMEOUT_INDEFINITE); - return future; - } - - @SuppressWarnings("deprecation") - @Override - public ListenableFuture submitListenable(Callable task) { - ListenableFutureTask future = new ListenableFutureTask<>(task); - execute(future, TIMEOUT_INDEFINITE); - return future; - } - /** * Template method for the actual execution of a task. *

The default implementation creates a new Thread and starts it. diff --git a/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java b/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java index 0669f7ea7c8..a9878aab2e2 100644 --- a/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java +++ b/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java @@ -23,13 +23,11 @@ import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.RejectedExecutionException; -import org.springframework.core.task.AsyncListenableTaskExecutor; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.TaskDecorator; import org.springframework.core.task.TaskRejectedException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureTask; /** * Adapter that takes a JDK {@code java.util.concurrent.Executor} and @@ -43,8 +41,8 @@ import org.springframework.util.concurrent.ListenableFutureTask; * @see java.util.concurrent.ExecutorService * @see java.util.concurrent.Executors */ -@SuppressWarnings({"deprecation", "removal"}) -public class TaskExecutorAdapter implements AsyncListenableTaskExecutor { +@SuppressWarnings("deprecation") +public class TaskExecutorAdapter implements AsyncTaskExecutor { private final Executor concurrentExecutor; @@ -133,30 +131,6 @@ public class TaskExecutorAdapter implements AsyncListenableTaskExecutor { } } - @Override - public ListenableFuture submitListenable(Runnable task) { - try { - ListenableFutureTask future = new ListenableFutureTask<>(task, null); - doExecute(this.concurrentExecutor, this.taskDecorator, future); - return future; - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException(this.concurrentExecutor, task, ex); - } - } - - @Override - public ListenableFuture submitListenable(Callable task) { - try { - ListenableFutureTask future = new ListenableFutureTask<>(task); - doExecute(this.concurrentExecutor, this.taskDecorator, future); - return future; - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException(this.concurrentExecutor, task, ex); - } - } - /** * Actually execute the given {@code Runnable} (which may be a user-supplied task diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index d4b670718c7..5a328468429 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -23,7 +23,6 @@ import java.nio.charset.Charset; import java.util.BitSet; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Locale; @@ -695,48 +694,4 @@ public class MimeType implements Comparable, Serializable { return map; } - - /** - * Comparator to sort {@link MimeType MimeTypes} in order of specificity. - * - * @param the type of mime types that may be compared by this comparator - * @deprecated As of 6.0, with no direct replacement - */ - @Deprecated(since = "6.0", forRemoval = true) - public static class SpecificityComparator implements Comparator { - - @Override - public int compare(T mimeType1, T mimeType2) { - if (mimeType1.isWildcardType() && !mimeType2.isWildcardType()) { // */* < audio/* - return 1; - } - else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */* - return -1; - } - else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == text/html - return 0; - } - else { // mediaType1.getType().equals(mediaType2.getType()) - if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic - return 1; - } - else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/* - return -1; - } - else if (!mimeType1.getSubtype().equals(mimeType2.getSubtype())) { // audio/basic == audio/wave - return 0; - } - else { // mediaType2.getSubtype().equals(mediaType2.getSubtype()) - return compareParameters(mimeType1, mimeType2); - } - } - } - - protected int compareParameters(T mimeType1, T mimeType2) { - int paramsSize1 = mimeType1.getParameters().size(); - int paramsSize2 = mimeType2.getParameters().size(); - return Integer.compare(paramsSize2, paramsSize1); // audio/basic;level=1 < audio/basic - } - } - } diff --git a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java index 93c946ec676..f3a9f2b688c 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java +++ b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -51,14 +50,6 @@ public abstract class MimeTypeUtils { 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; - /** - * Comparator formally used by {@link #sortBySpecificity(List)}. - * @deprecated As of 6.0, with no direct replacement - */ - @SuppressWarnings("removal") - @Deprecated(since = "6.0", forRemoval = true) - public static final Comparator SPECIFICITY_COMPARATOR = new MimeType.SpecificityComparator<>(); - /** * Public constant mime type that includes all media ranges (i.e. "*/*"). */ diff --git a/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java b/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java index 78cb9a2c1ff..8e1d6094c64 100644 --- a/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java +++ b/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java @@ -49,24 +49,6 @@ public class PropertyPlaceholderHelper { this(placeholderPrefix, placeholderSuffix, null, null, true); } - /** - * Create a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix. - * @param placeholderPrefix the prefix that denotes the start of a placeholder - * @param placeholderSuffix the suffix that denotes the end of a placeholder - * @param valueSeparator the separating character between the placeholder variable - * and the associated default value, if any - * @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should - * be ignored ({@code true}) or cause an exception ({@code false}) - * @deprecated as of 6.2, in favor of - * {@link PropertyPlaceholderHelper#PropertyPlaceholderHelper(String, String, String, Character, boolean)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix, - @Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) { - - this(placeholderPrefix, placeholderSuffix, valueSeparator, null, ignoreUnresolvablePlaceholders); - } - /** * Create a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix. * @param placeholderPrefix the prefix that denotes the start of a placeholder diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/CompletableToListenableFutureAdapter.java b/spring-core/src/main/java/org/springframework/util/concurrent/CompletableToListenableFutureAdapter.java deleted file mode 100644 index 0c50053c327..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/CompletableToListenableFutureAdapter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Adapts a {@link CompletableFuture} or {@link CompletionStage} into a - * Spring {@link ListenableFuture}. - * - * @author Sebastien Deleuze - * @author Juergen Hoeller - * @since 4.2 - * @param the result type returned by this Future's {@code get} method - * @deprecated as of 6.0, with no concrete replacement - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public class CompletableToListenableFutureAdapter implements ListenableFuture { - - private final CompletableFuture completableFuture; - - private final ListenableFutureCallbackRegistry callbacks = new ListenableFutureCallbackRegistry<>(); - - - /** - * Create a new adapter for the given {@link CompletionStage}. - * @since 4.3.7 - */ - public CompletableToListenableFutureAdapter(CompletionStage completionStage) { - this(completionStage.toCompletableFuture()); - } - - /** - * Create a new adapter for the given {@link CompletableFuture}. - */ - public CompletableToListenableFutureAdapter(CompletableFuture completableFuture) { - this.completableFuture = completableFuture; - this.completableFuture.whenComplete((result, ex) -> { - if (ex != null) { - this.callbacks.failure(ex); - } - else { - this.callbacks.success(result); - } - }); - } - - - @Override - public void addCallback(ListenableFutureCallback callback) { - this.callbacks.addCallback(callback); - } - - @Override - public void addCallback(SuccessCallback successCallback, FailureCallback failureCallback) { - this.callbacks.addSuccessCallback(successCallback); - this.callbacks.addFailureCallback(failureCallback); - } - - @Override - public CompletableFuture completable() { - return this.completableFuture; - } - - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return this.completableFuture.cancel(mayInterruptIfRunning); - } - - @Override - public boolean isCancelled() { - return this.completableFuture.isCancelled(); - } - - @Override - public boolean isDone() { - return this.completableFuture.isDone(); - } - - @Override - public T get() throws InterruptedException, ExecutionException { - return this.completableFuture.get(); - } - - @Override - public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return this.completableFuture.get(timeout, unit); - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java b/spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java deleted file mode 100644 index e24adfdd6f7..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.function.BiConsumer; - -/** - * Failure callback for a {@link ListenableFuture}. - * - * @author Sebastien Deleuze - * @since 4.1 - * @deprecated as of 6.0, in favor of - * {@link java.util.concurrent.CompletableFuture#whenComplete(BiConsumer)} - */ -@Deprecated(since = "6.0", forRemoval = true) -@FunctionalInterface -public interface FailureCallback { - - /** - * Called when the {@link ListenableFuture} completes with failure. - *

Note that Exceptions raised by this method are ignored. - * @param ex the failure - */ - void onFailure(Throwable ex); - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java deleted file mode 100644 index fc8c0e5f207..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; -import java.util.function.BiConsumer; - -/** - * Extend {@link Future} with the capability to accept completion callbacks. - * If the future has completed when the callback is added, the callback is - * triggered immediately. - * - *

Inspired by {@code com.google.common.util.concurrent.ListenableFuture}. - * - * @author Arjen Poutsma - * @author Sebastien Deleuze - * @author Juergen Hoeller - * @since 4.0 - * @param the result type returned by this Future's {@code get} method - * @deprecated as of 6.0, in favor of {@link CompletableFuture} - */ -@Deprecated(since = "6.0", forRemoval = true) -public interface ListenableFuture extends Future { - - /** - * Register the given {@code ListenableFutureCallback}. - * @param callback the callback to register - * @deprecated as of 6.0, in favor of - * {@link CompletableFuture#whenComplete(BiConsumer)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - void addCallback(ListenableFutureCallback callback); - - /** - * Java 8 lambda-friendly alternative with success and failure callbacks. - * @param successCallback the success callback - * @param failureCallback the failure callback - * @since 4.1 - * @deprecated as of 6.0, in favor of - * {@link CompletableFuture#whenComplete(BiConsumer)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - void addCallback(SuccessCallback successCallback, FailureCallback failureCallback); - - - /** - * Expose this {@link ListenableFuture} as a JDK {@link CompletableFuture}. - * @since 5.0 - */ - @SuppressWarnings("NullAway") - default CompletableFuture completable() { - CompletableFuture completable = new DelegatingCompletableFuture<>(this); - addCallback(completable::complete, completable::completeExceptionally); - return completable; - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureAdapter.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureAdapter.java deleted file mode 100644 index 0ddc5bc4290..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureAdapter.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.concurrent.ExecutionException; - -import org.springframework.lang.Nullable; - -/** - * Abstract class that adapts a {@link ListenableFuture} parameterized over S into a - * {@code ListenableFuture} parameterized over T. All methods are delegated to the - * adaptee, where {@link #get()}, {@link #get(long, java.util.concurrent.TimeUnit)}, - * and {@link ListenableFutureCallback#onSuccess(Object)} call {@link #adapt(Object)} - * on the adaptee's result. - * - * @author Arjen Poutsma - * @since 4.0 - * @param the type of this {@code Future} - * @param the type of the adaptee's {@code Future} - * @deprecated as of 6.0, in favor of - * {@link java.util.concurrent.CompletableFuture} - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public abstract class ListenableFutureAdapter extends FutureAdapter implements ListenableFuture { - - /** - * Construct a new {@code ListenableFutureAdapter} with the given adaptee. - * @param adaptee the future to adapt to - */ - protected ListenableFutureAdapter(ListenableFuture adaptee) { - super(adaptee); - } - - - @Override - public void addCallback(final ListenableFutureCallback callback) { - addCallback(callback, callback); - } - - @Override - public void addCallback(final SuccessCallback successCallback, final FailureCallback failureCallback) { - ListenableFuture listenableAdaptee = (ListenableFuture) getAdaptee(); - listenableAdaptee.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(@Nullable S result) { - T adapted = null; - if (result != null) { - try { - adapted = adaptInternal(result); - } - catch (ExecutionException ex) { - Throwable cause = ex.getCause(); - onFailure(cause != null ? cause : ex); - return; - } - catch (Throwable ex) { - onFailure(ex); - return; - } - } - successCallback.onSuccess(adapted); - } - - @Override - public void onFailure(Throwable ex) { - failureCallback.onFailure(ex); - } - }); - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java deleted file mode 100644 index dfd0f4e2448..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.function.BiConsumer; - -/** - * Callback mechanism for the outcome, success or failure, from a - * {@link ListenableFuture}. - * - * @author Arjen Poutsma - * @author Sebastien Deleuze - * @since 4.0 - * @param the result type - * @deprecated as of 6.0, in favor of - * {@link java.util.concurrent.CompletableFuture#whenComplete(BiConsumer)} - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public interface ListenableFutureCallback extends SuccessCallback, FailureCallback { - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java deleted file mode 100644 index 178d549c162..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.ArrayDeque; -import java.util.Queue; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Helper class for {@link ListenableFuture} implementations that maintains a queue - * of success and failure callbacks and helps to notify them. - * - *

Inspired by {@code com.google.common.util.concurrent.ExecutionList}. - * - * @author Arjen Poutsma - * @author Sebastien Deleuze - * @author Rossen Stoyanchev - * @since 4.0 - * @param the callback result type - * @deprecated as of 6.0, with no concrete replacement - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public class ListenableFutureCallbackRegistry { - - private final Queue> successCallbacks = new ArrayDeque<>(1); - - private final Queue failureCallbacks = new ArrayDeque<>(1); - - private State state = State.NEW; - - @Nullable - private Object result; - - private final Object mutex = new Object(); - - - /** - * Add the given callback to this registry. - * @param callback the callback to add - */ - public void addCallback(ListenableFutureCallback callback) { - Assert.notNull(callback, "'callback' must not be null"); - synchronized (this.mutex) { - switch (this.state) { - case NEW -> { - this.successCallbacks.add(callback); - this.failureCallbacks.add(callback); - } - case SUCCESS -> notifySuccess(callback); - case FAILURE -> notifyFailure(callback); - } - } - } - - @SuppressWarnings("unchecked") - private void notifySuccess(SuccessCallback callback) { - try { - callback.onSuccess((T) this.result); - } - catch (Throwable ex) { - // Ignore - } - } - - private void notifyFailure(FailureCallback callback) { - Assert.state(this.result instanceof Throwable, "No Throwable result for failure state"); - try { - callback.onFailure((Throwable) this.result); - } - catch (Throwable ex) { - // Ignore - } - } - - /** - * Add the given success callback to this registry. - * @param callback the success callback to add - * @since 4.1 - */ - public void addSuccessCallback(SuccessCallback callback) { - Assert.notNull(callback, "'callback' must not be null"); - synchronized (this.mutex) { - switch (this.state) { - case NEW -> this.successCallbacks.add(callback); - case SUCCESS -> notifySuccess(callback); - } - } - } - - /** - * Add the given failure callback to this registry. - * @param callback the failure callback to add - * @since 4.1 - */ - public void addFailureCallback(FailureCallback callback) { - Assert.notNull(callback, "'callback' must not be null"); - synchronized (this.mutex) { - switch (this.state) { - case NEW -> this.failureCallbacks.add(callback); - case FAILURE -> notifyFailure(callback); - } - } - } - - /** - * Trigger a {@link ListenableFutureCallback#onSuccess(Object)} call on all - * added callbacks with the given result. - * @param result the result to trigger the callbacks with - */ - public void success(@Nullable T result) { - synchronized (this.mutex) { - this.state = State.SUCCESS; - this.result = result; - SuccessCallback callback; - while ((callback = this.successCallbacks.poll()) != null) { - notifySuccess(callback); - } - } - } - - /** - * Trigger a {@link ListenableFutureCallback#onFailure(Throwable)} call on all - * added callbacks with the given {@code Throwable}. - * @param ex the exception to trigger the callbacks with - */ - public void failure(Throwable ex) { - synchronized (this.mutex) { - this.state = State.FAILURE; - this.result = ex; - FailureCallback callback; - while ((callback = this.failureCallbacks.poll()) != null) { - notifyFailure(callback); - } - } - } - - - private enum State {NEW, SUCCESS, FAILURE} - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureTask.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureTask.java deleted file mode 100644 index 271fc083263..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureTask.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; - -import org.springframework.lang.Nullable; - -/** - * Extension of {@link FutureTask} that implements {@link ListenableFuture}. - * - * @author Arjen Poutsma - * @since 4.0 - * @param the result type returned by this Future's {@code get} method - * @deprecated as of 6.0, with no concrete replacement - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public class ListenableFutureTask extends FutureTask implements ListenableFuture { - - private final ListenableFutureCallbackRegistry callbacks = new ListenableFutureCallbackRegistry<>(); - - - /** - * Create a new {@code ListenableFutureTask} that will, upon running, - * execute the given {@link Callable}. - * @param callable the callable task - */ - public ListenableFutureTask(Callable callable) { - super(callable); - } - - /** - * Create a {@code ListenableFutureTask} that will, upon running, - * execute the given {@link Runnable}, and arrange that {@link #get()} - * will return the given result on successful completion. - * @param runnable the runnable task - * @param result the result to return on successful completion - */ - public ListenableFutureTask(Runnable runnable, @Nullable T result) { - super(runnable, result); - } - - - @Override - public void addCallback(ListenableFutureCallback callback) { - this.callbacks.addCallback(callback); - } - - @Override - public void addCallback(SuccessCallback successCallback, FailureCallback failureCallback) { - this.callbacks.addSuccessCallback(successCallback); - this.callbacks.addFailureCallback(failureCallback); - } - - @Override - @SuppressWarnings("NullAway") - public CompletableFuture completable() { - CompletableFuture completable = new DelegatingCompletableFuture<>(this); - this.callbacks.addSuccessCallback(completable::complete); - this.callbacks.addFailureCallback(completable::completeExceptionally); - return completable; - } - - - @Override - protected void done() { - Throwable cause; - try { - T result = get(); - this.callbacks.success(result); - return; - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - return; - } - catch (ExecutionException ex) { - cause = ex.getCause(); - if (cause == null) { - cause = ex; - } - } - catch (Throwable ex) { - cause = ex; - } - this.callbacks.failure(cause); - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/MonoToListenableFutureAdapter.java b/spring-core/src/main/java/org/springframework/util/concurrent/MonoToListenableFutureAdapter.java deleted file mode 100644 index f55162a0856..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/MonoToListenableFutureAdapter.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import reactor.core.publisher.Mono; - -/** - * Adapts a {@link Mono} into a {@link ListenableFuture} by obtaining a - * {@code CompletableFuture} from the {@code Mono} via {@link Mono#toFuture()} - * and then adapting it with {@link CompletableToListenableFutureAdapter}. - * - * @author Rossen Stoyanchev - * @author Stephane Maldini - * @since 5.1 - * @param the object type - * @deprecated as of 6.0, in favor of {@link Mono#toFuture()} - */ -@Deprecated(since = "6.0") -@SuppressWarnings("removal") -public class MonoToListenableFutureAdapter extends CompletableToListenableFutureAdapter { - - public MonoToListenableFutureAdapter(Mono mono) { - super(mono.toFuture()); - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/SettableListenableFuture.java b/spring-core/src/main/java/org/springframework/util/concurrent/SettableListenableFuture.java deleted file mode 100644 index e7cb0c75567..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/SettableListenableFuture.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * A {@link ListenableFuture} whose value can be set via {@link #set(Object)} - * or {@link #setException(Throwable)}. It may also get cancelled. - * - *

Inspired by {@code com.google.common.util.concurrent.SettableFuture}. - * - * @author Mattias Severson - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @since 4.1 - * @param the result type returned by this Future's {@code get} method - * @deprecated as of 6.0, in favor of {@link CompletableFuture} - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public class SettableListenableFuture implements ListenableFuture { - - private static final Callable DUMMY_CALLABLE = () -> { - throw new IllegalStateException("Should never be called"); - }; - - - private final SettableTask settableTask = new SettableTask<>(); - - - /** - * Set the value of this future. This method will return {@code true} if the - * value was set successfully, or {@code false} if the future has already been - * set or cancelled. - * @param value the value that will be set - * @return {@code true} if the value was successfully set, else {@code false} - */ - public boolean set(@Nullable T value) { - return this.settableTask.setResultValue(value); - } - - /** - * Set the exception of this future. This method will return {@code true} if the - * exception was set successfully, or {@code false} if the future has already been - * set or cancelled. - * @param exception the value that will be set - * @return {@code true} if the exception was successfully set, else {@code false} - */ - public boolean setException(Throwable exception) { - Assert.notNull(exception, "Exception must not be null"); - return this.settableTask.setExceptionResult(exception); - } - - - @Override - public void addCallback(ListenableFutureCallback callback) { - this.settableTask.addCallback(callback); - } - - @Override - public void addCallback(SuccessCallback successCallback, FailureCallback failureCallback) { - this.settableTask.addCallback(successCallback, failureCallback); - } - - @Override - public CompletableFuture completable() { - return this.settableTask.completable(); - } - - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - boolean cancelled = this.settableTask.cancel(mayInterruptIfRunning); - if (cancelled && mayInterruptIfRunning) { - interruptTask(); - } - return cancelled; - } - - @Override - public boolean isCancelled() { - return this.settableTask.isCancelled(); - } - - @Override - public boolean isDone() { - return this.settableTask.isDone(); - } - - /** - * Retrieve the value. - *

This method returns the value if it has been set via {@link #set(Object)}, - * throws an {@link java.util.concurrent.ExecutionException} if an exception has - * been set via {@link #setException(Throwable)}, or throws a - * {@link java.util.concurrent.CancellationException} if the future has been cancelled. - * @return the value associated with this future - */ - @Nullable - @Override - public T get() throws InterruptedException, ExecutionException { - return this.settableTask.get(); - } - - /** - * Retrieve the value. - *

This method returns the value if it has been set via {@link #set(Object)}, - * throws an {@link java.util.concurrent.ExecutionException} if an exception has - * been set via {@link #setException(Throwable)}, or throws a - * {@link java.util.concurrent.CancellationException} if the future has been cancelled. - * @param timeout the maximum time to wait - * @param unit the unit of the timeout argument - * @return the value associated with this future - */ - @Nullable - @Override - public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return this.settableTask.get(timeout, unit); - } - - /** - * Subclasses can override this method to implement interruption of the future's - * computation. The method is invoked automatically by a successful call to - * {@link #cancel(boolean) cancel(true)}. - *

The default implementation is empty. - */ - protected void interruptTask() { - } - - - private static class SettableTask extends ListenableFutureTask { - - @Nullable - private volatile Thread completingThread; - - @SuppressWarnings("unchecked") - public SettableTask() { - super((Callable) DUMMY_CALLABLE); - } - - public boolean setResultValue(@Nullable T value) { - set(value); - return checkCompletingThread(); - } - - public boolean setExceptionResult(Throwable exception) { - setException(exception); - return checkCompletingThread(); - } - - @Override - protected void done() { - if (!isCancelled()) { - // Implicitly invoked by set/setException: store current thread for - // determining whether the given result has actually triggered completion - // (since FutureTask.set/setException unfortunately don't expose that) - this.completingThread = Thread.currentThread(); - } - super.done(); - } - - private boolean checkCompletingThread() { - boolean check = (this.completingThread == Thread.currentThread()); - if (check) { - this.completingThread = null; // only first match actually counts - } - return check; - } - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/SuccessCallback.java b/spring-core/src/main/java/org/springframework/util/concurrent/SuccessCallback.java deleted file mode 100644 index 8ecba36eb61..00000000000 --- a/spring-core/src/main/java/org/springframework/util/concurrent/SuccessCallback.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.function.BiConsumer; - -import org.springframework.lang.Nullable; - -/** - * Success callback for a {@link ListenableFuture}. - * - * @author Sebastien Deleuze - * @since 4.1 - * @param the result type - * @deprecated as of 6.0, in favor of - * {@link java.util.concurrent.CompletableFuture#whenComplete(BiConsumer)} - */ -@Deprecated(since = "6.0", forRemoval = true) -@FunctionalInterface -public interface SuccessCallback { - - /** - * Called when the {@link ListenableFuture} completes with success. - *

Note that Exceptions raised by this method are ignored. - * @param result the result - */ - void onSuccess(@Nullable T result); - -} diff --git a/spring-core/src/test/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrarTests.java b/spring-core/src/test/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrarTests.java index a8c93b1ec9d..a781a6cb873 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrarTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrarTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ class FilePatternResourceHintsRegistrarTests { @Test void registerWithMultipleClasspathLocations() { - FilePatternResourceHintsRegistrar.forClassPathLocations("").withClasspathLocations("META-INF") + FilePatternResourceHintsRegistrar.forClassPathLocations("").withClassPathLocations("META-INF") .withFilePrefixes("test").withFileExtensions(".txt") .registerHints(this.hints, null); assertThat(this.hints.resourcePatternHints()).singleElement() @@ -133,7 +133,7 @@ class FilePatternResourceHintsRegistrarTests { @Test void registerWithNonExistingLocationDoesNotRegisterHint() { FilePatternResourceHintsRegistrar.forClassPathLocations("does-not-exist/") - .withClasspathLocations("another-does-not-exist/") + .withClassPathLocations("another-does-not-exist/") .withFilePrefixes("test").withFileExtensions(".txt") .registerHints(this.hints, null); assertThat(this.hints.resourcePatternHints()).isEmpty(); diff --git a/spring-core/src/test/java/org/springframework/util/concurrent/ListenableFutureTaskTests.java b/spring-core/src/test/java/org/springframework/util/concurrent/ListenableFutureTaskTests.java deleted file mode 100644 index 920b5ebd448..00000000000 --- a/spring-core/src/test/java/org/springframework/util/concurrent/ListenableFutureTaskTests.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; - -/** - * @author Arjen Poutsma - * @author Sebastien Deleuze - */ -@SuppressWarnings({"deprecation", "removal"}) -class ListenableFutureTaskTests { - - @Test - void success() throws Exception { - final String s = "Hello World"; - Callable callable = () -> s; - - ListenableFutureTask task = new ListenableFutureTask<>(callable); - task.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - assertThat(result).isEqualTo(s); - } - - @Override - public void onFailure(Throwable ex) { - throw new AssertionError(ex.getMessage(), ex); - } - }); - task.run(); - - assertThat(task.get()).isSameAs(s); - assertThat(task.completable().get()).isSameAs(s); - task.completable().thenAccept(v -> assertThat(v).isSameAs(s)); - } - - @Test - void failure() { - final String s = "Hello World"; - Callable callable = () -> { - throw new IOException(s); - }; - - ListenableFutureTask task = new ListenableFutureTask<>(callable); - task.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - fail("onSuccess not expected"); - } - - @Override - public void onFailure(Throwable ex) { - assertThat(ex.getMessage()).isEqualTo(s); - } - }); - task.run(); - - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(task::get) - .havingCause() - .withMessage(s); - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(task.completable()::get) - .havingCause() - .withMessage(s); - } - - @Test - void successWithLambdas() throws Exception { - final String s = "Hello World"; - Callable callable = () -> s; - - SuccessCallback successCallback = mock(); - FailureCallback failureCallback = mock(); - ListenableFutureTask task = new ListenableFutureTask<>(callable); - task.addCallback(successCallback, failureCallback); - task.run(); - verify(successCallback).onSuccess(s); - verifyNoInteractions(failureCallback); - - assertThat(task.get()).isSameAs(s); - assertThat(task.completable().get()).isSameAs(s); - task.completable().thenAccept(v -> assertThat(v).isSameAs(s)); - } - - @Test - void failureWithLambdas() { - final String s = "Hello World"; - IOException ex = new IOException(s); - Callable callable = () -> { - throw ex; - }; - - SuccessCallback successCallback = mock(); - FailureCallback failureCallback = mock(); - ListenableFutureTask task = new ListenableFutureTask<>(callable); - task.addCallback(successCallback, failureCallback); - task.run(); - verify(failureCallback).onFailure(ex); - verifyNoInteractions(successCallback); - - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(task::get) - .havingCause() - .withMessage(s); - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(task.completable()::get) - .havingCause() - .withMessage(s); - } - -} diff --git a/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java b/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java deleted file mode 100644 index 5b7a139f840..00000000000 --- a/spring-core/src/test/java/org/springframework/util/concurrent/MonoToListenableFutureAdapterTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.time.Duration; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicReference; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MonoToListenableFutureAdapter}. - * - * @author Rossen Stoyanchev - */ -@SuppressWarnings({"deprecation", "removal"}) -class MonoToListenableFutureAdapterTests { - - @Test - void success() { - String expected = "one"; - AtomicReference actual = new AtomicReference<>(); - ListenableFuture future = new MonoToListenableFutureAdapter<>(Mono.just(expected)); - future.addCallback(actual::set, actual::set); - - assertThat(actual.get()).isEqualTo(expected); - } - - @Test - @SuppressWarnings("deprecation") - void failure() { - Throwable expected = new IllegalStateException("oops"); - AtomicReference actual = new AtomicReference<>(); - ListenableFuture future = new MonoToListenableFutureAdapter<>(Mono.error(expected)); - future.addCallback(actual::set, actual::set); - - assertThat(actual.get()).isEqualTo(expected); - } - - @Test - void cancellation() { - Mono mono = Mono.delay(Duration.ofSeconds(60)); - Future future = new MonoToListenableFutureAdapter<>(mono); - - assertThat(future.cancel(true)).isTrue(); - assertThat(future.isCancelled()).isTrue(); - } - - @Test - void cancellationAfterTerminated() { - Future future = new MonoToListenableFutureAdapter<>(Mono.empty()); - - assertThat(future.cancel(true)).as("Should return false if task already completed").isFalse(); - assertThat(future.isCancelled()).isFalse(); - } - -} diff --git a/spring-core/src/test/java/org/springframework/util/concurrent/SettableListenableFutureTests.java b/spring-core/src/test/java/org/springframework/util/concurrent/SettableListenableFutureTests.java deleted file mode 100644 index d79296dd099..00000000000 --- a/spring-core/src/test/java/org/springframework/util/concurrent/SettableListenableFutureTests.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util.concurrent; - -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -/** - * @author Mattias Severson - * @author Juergen Hoeller - */ -@SuppressWarnings({"deprecation", "removal"}) -class SettableListenableFutureTests { - - private final SettableListenableFuture settableListenableFuture = new SettableListenableFuture<>(); - - - @Test - void validateInitialValues() { - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isFalse(); - } - - @Test - void returnsSetValue() throws ExecutionException, InterruptedException { - String string = "hello"; - assertThat(settableListenableFuture.set(string)).isTrue(); - assertThat(settableListenableFuture.get()).isEqualTo(string); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void returnsSetValueFromCompletable() throws ExecutionException, InterruptedException { - String string = "hello"; - assertThat(settableListenableFuture.set(string)).isTrue(); - Future completable = settableListenableFuture.completable(); - assertThat(completable.get()).isEqualTo(string); - assertThat(completable.isCancelled()).isFalse(); - assertThat(completable.isDone()).isTrue(); - } - - @Test - void setValueUpdatesDoneStatus() { - settableListenableFuture.set("hello"); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void throwsSetExceptionWrappedInExecutionException() { - Throwable exception = new RuntimeException(); - assertThat(settableListenableFuture.setException(exception)).isTrue(); - - assertThatExceptionOfType(ExecutionException.class).isThrownBy( - settableListenableFuture::get) - .withCause(exception); - - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void throwsSetExceptionWrappedInExecutionExceptionFromCompletable() { - Throwable exception = new RuntimeException(); - assertThat(settableListenableFuture.setException(exception)).isTrue(); - Future completable = settableListenableFuture.completable(); - - assertThatExceptionOfType(ExecutionException.class).isThrownBy( - completable::get) - .withCause(exception); - - assertThat(completable.isCancelled()).isFalse(); - assertThat(completable.isDone()).isTrue(); - } - - @Test - void throwsSetErrorWrappedInExecutionException() { - Throwable exception = new OutOfMemoryError(); - assertThat(settableListenableFuture.setException(exception)).isTrue(); - - assertThatExceptionOfType(ExecutionException.class).isThrownBy( - settableListenableFuture::get) - .withCause(exception); - - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void throwsSetErrorWrappedInExecutionExceptionFromCompletable() { - Throwable exception = new OutOfMemoryError(); - assertThat(settableListenableFuture.setException(exception)).isTrue(); - Future completable = settableListenableFuture.completable(); - - assertThatExceptionOfType(ExecutionException.class).isThrownBy( - completable::get) - .withCause(exception); - - assertThat(completable.isCancelled()).isFalse(); - assertThat(completable.isDone()).isTrue(); - } - - @Test - void setValueTriggersCallback() { - String string = "hello"; - final String[] callbackHolder = new String[1]; - - settableListenableFuture.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - callbackHolder[0] = result; - } - - @Override - public void onFailure(Throwable ex) { - throw new AssertionError("Expected onSuccess() to be called", ex); - } - }); - - settableListenableFuture.set(string); - assertThat(callbackHolder[0]).isEqualTo(string); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void setValueTriggersCallbackOnlyOnce() { - String string = "hello"; - final String[] callbackHolder = new String[1]; - - settableListenableFuture.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - callbackHolder[0] = result; - } - - @Override - public void onFailure(Throwable ex) { - throw new AssertionError("Expected onSuccess() to be called", ex); - } - }); - - settableListenableFuture.set(string); - assertThat(settableListenableFuture.set("good bye")).isFalse(); - assertThat(callbackHolder[0]).isEqualTo(string); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void setExceptionTriggersCallback() { - Throwable exception = new RuntimeException(); - final Throwable[] callbackHolder = new Throwable[1]; - - settableListenableFuture.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - fail("Expected onFailure() to be called"); - } - - @Override - public void onFailure(Throwable ex) { - callbackHolder[0] = ex; - } - }); - - settableListenableFuture.setException(exception); - assertThat(callbackHolder[0]).isEqualTo(exception); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void setExceptionTriggersCallbackOnlyOnce() { - Throwable exception = new RuntimeException(); - final Throwable[] callbackHolder = new Throwable[1]; - - settableListenableFuture.addCallback(new ListenableFutureCallback<>() { - @Override - public void onSuccess(String result) { - fail("Expected onFailure() to be called"); - } - - @Override - public void onFailure(Throwable ex) { - callbackHolder[0] = ex; - } - }); - - settableListenableFuture.setException(exception); - assertThat(settableListenableFuture.setException(new IllegalArgumentException())).isFalse(); - assertThat(callbackHolder[0]).isEqualTo(exception); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void nullIsAcceptedAsValueToSet() throws ExecutionException, InterruptedException { - settableListenableFuture.set(null); - assertThat(settableListenableFuture.get()).isNull(); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void getWaitsForCompletion() throws ExecutionException, InterruptedException { - final String string = "hello"; - - new Thread(() -> { - try { - Thread.sleep(20L); - settableListenableFuture.set(string); - } - catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - }).start(); - - String value = settableListenableFuture.get(); - assertThat(value).isEqualTo(string); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void getWithTimeoutThrowsTimeoutException() { - assertThatExceptionOfType(TimeoutException.class).isThrownBy(() -> - settableListenableFuture.get(1L, TimeUnit.MILLISECONDS)); - } - - @Test - void getWithTimeoutWaitsForCompletion() throws ExecutionException, InterruptedException, TimeoutException { - final String string = "hello"; - - new Thread(() -> { - try { - Thread.sleep(20L); - settableListenableFuture.set(string); - } - catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - }).start(); - - String value = settableListenableFuture.get(500L, TimeUnit.MILLISECONDS); - assertThat(value).isEqualTo(string); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void cancelPreventsValueFromBeingSet() { - assertThat(settableListenableFuture.cancel(true)).isTrue(); - assertThat(settableListenableFuture.set("hello")).isFalse(); - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void cancelSetsFutureToDone() { - settableListenableFuture.cancel(true); - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void cancelWithMayInterruptIfRunningTrueCallsOverriddenMethod() { - InterruptibleSettableListenableFuture interruptibleFuture = new InterruptibleSettableListenableFuture(); - assertThat(interruptibleFuture.cancel(true)).isTrue(); - assertThat(interruptibleFuture.calledInterruptTask()).isTrue(); - assertThat(interruptibleFuture.isCancelled()).isTrue(); - assertThat(interruptibleFuture.isDone()).isTrue(); - } - - @Test - void cancelWithMayInterruptIfRunningFalseDoesNotCallOverriddenMethod() { - InterruptibleSettableListenableFuture interruptibleFuture = new InterruptibleSettableListenableFuture(); - assertThat(interruptibleFuture.cancel(false)).isTrue(); - assertThat(interruptibleFuture.calledInterruptTask()).isFalse(); - assertThat(interruptibleFuture.isCancelled()).isTrue(); - assertThat(interruptibleFuture.isDone()).isTrue(); - } - - @Test - void setPreventsCancel() { - assertThat(settableListenableFuture.set("hello")).isTrue(); - assertThat(settableListenableFuture.cancel(true)).isFalse(); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void cancelPreventsExceptionFromBeingSet() { - assertThat(settableListenableFuture.cancel(true)).isTrue(); - assertThat(settableListenableFuture.setException(new RuntimeException())).isFalse(); - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void setExceptionPreventsCancel() { - assertThat(settableListenableFuture.setException(new RuntimeException())).isTrue(); - assertThat(settableListenableFuture.cancel(true)).isFalse(); - assertThat(settableListenableFuture.isCancelled()).isFalse(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void cancelStateThrowsExceptionWhenCallingGet() { - settableListenableFuture.cancel(true); - - assertThatExceptionOfType(CancellationException.class).isThrownBy(settableListenableFuture::get); - - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - void cancelStateThrowsExceptionWhenCallingGetWithTimeout() { - new Thread(() -> { - try { - Thread.sleep(20L); - settableListenableFuture.cancel(true); - } - catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - }).start(); - - assertThatExceptionOfType(CancellationException.class).isThrownBy(() -> - settableListenableFuture.get(500L, TimeUnit.MILLISECONDS)); - - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - @SuppressWarnings({"rawtypes", "unchecked"}) - public void cancelDoesNotNotifyCallbacksOnSet() { - ListenableFutureCallback callback = mock(); - settableListenableFuture.addCallback(callback); - settableListenableFuture.cancel(true); - - verify(callback).onFailure(any(CancellationException.class)); - verifyNoMoreInteractions(callback); - - settableListenableFuture.set("hello"); - verifyNoMoreInteractions(callback); - - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - @Test - @SuppressWarnings({"rawtypes", "unchecked"}) - public void cancelDoesNotNotifyCallbacksOnSetException() { - ListenableFutureCallback callback = mock(); - settableListenableFuture.addCallback(callback); - settableListenableFuture.cancel(true); - - verify(callback).onFailure(any(CancellationException.class)); - verifyNoMoreInteractions(callback); - - settableListenableFuture.setException(new RuntimeException()); - verifyNoMoreInteractions(callback); - - assertThat(settableListenableFuture.isCancelled()).isTrue(); - assertThat(settableListenableFuture.isDone()).isTrue(); - } - - - private static class InterruptibleSettableListenableFuture extends SettableListenableFuture { - - private boolean interrupted = false; - - @Override - protected void interruptTask() { - interrupted = true; - } - - boolean calledInterruptTask() { - return interrupted; - } - } - -} diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java b/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java index 32247c95b94..5b3deb8f2c9 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ExpressionState.java @@ -211,69 +211,11 @@ public class ExpressionState { initScopeRootObjects().push(getActiveContextObject()); } - /** - * Enter a new scope with a new {@linkplain #getActiveContextObject() root - * context object} and a new local variable scope containing the supplied - * name/value pair. - * @param name the name of the local variable - * @param value the value of the local variable - * @deprecated as of 6.2 with no replacement; to be removed in 7.0 - */ - @Deprecated(since = "6.2", forRemoval = true) - public void enterScope(String name, Object value) { - initVariableScopes().push(new VariableScope(name, value)); - initScopeRootObjects().push(getActiveContextObject()); - } - - /** - * Enter a new scope with a new {@linkplain #getActiveContextObject() root - * context object} and a new local variable scope containing the supplied - * name/value pairs. - * @param variables a map containing name/value pairs for local variables - * @deprecated as of 6.2 with no replacement; to be removed in 7.0 - */ - @Deprecated(since = "6.2", forRemoval = true) - public void enterScope(@Nullable Map variables) { - initVariableScopes().push(new VariableScope(variables)); - initScopeRootObjects().push(getActiveContextObject()); - } - public void exitScope() { initVariableScopes().pop(); initScopeRootObjects().pop(); } - /** - * Set a local variable with the given name to the supplied value within the - * current scope. - *

If a local variable with the given name already exists, it will be - * overwritten. - * @param name the name of the local variable - * @param value the value of the local variable - * @deprecated as of 6.2 with no replacement; to be removed in 7.0 - */ - @Deprecated(since = "6.2", forRemoval = true) - public void setLocalVariable(String name, Object value) { - initVariableScopes().element().setVariable(name, value); - } - - /** - * Look up the value of the local variable with the given name. - * @param name the name of the local variable - * @return the value of the local variable, or {@code null} if the variable - * does not exist in the current scope - * @deprecated as of 6.2 with no replacement; to be removed in 7.0 - */ - @Deprecated(since = "6.2", forRemoval = true) - @Nullable - public Object lookupLocalVariable(String name) { - for (VariableScope scope : initVariableScopes()) { - if (scope.definesVariable(name)) { - return scope.lookupVariable(name); - } - } - return null; - } private Deque initContextObjects() { if (this.contextObjects == null) { diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java index 94cc5d37016..b6b09c1fb76 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java @@ -123,17 +123,6 @@ public class Indexer extends SpelNodeImpl { private volatile CachedIndexState cachedIndexWriteState; - /** - * Create an {@code Indexer} with the given start position, end position, and - * index expression. - * @see #Indexer(boolean, int, int, SpelNodeImpl) - * @deprecated as of 6.2, in favor of {@link #Indexer(boolean, int, int, SpelNodeImpl)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public Indexer(int startPos, int endPos, SpelNodeImpl indexExpression) { - this(false, startPos, endPos, indexExpression); - } - /** * Create an {@code Indexer} with the given null-safe flag, start position, * end position, and index expression. diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java index f827eab9e9c..d2957bab9a4 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/ExpressionStateTests.java @@ -16,8 +16,6 @@ package org.springframework.expression.spel; -import java.util.Map; - import org.junit.jupiter.api.Test; import org.springframework.core.convert.TypeDescriptor; @@ -55,21 +53,6 @@ class ExpressionStateTests extends AbstractExpressionTests { assertThat(state.getEvaluationContext()).isEqualTo(context); } - @Test - @SuppressWarnings("removal") - void localVariables() { - Object value = state.lookupLocalVariable("foo"); - assertThat(value).isNull(); - - state.setLocalVariable("foo",34); - value = state.lookupLocalVariable("foo"); - assertThat(value).isEqualTo(34); - - state.setLocalVariable("foo", null); - value = state.lookupLocalVariable("foo"); - assertThat(value).isNull(); - } - @Test void globalVariables() { TypedValue typedValue = state.lookupVariable("foo"); @@ -86,41 +69,6 @@ class ExpressionStateTests extends AbstractExpressionTests { assertThat(typedValue.getTypeDescriptor().getType()).isEqualTo(String.class); } - @Test - @SuppressWarnings("removal") - void noVariableInterference() { - TypedValue typedValue = state.lookupVariable("foo"); - assertThat(typedValue).isEqualTo(TypedValue.NULL); - - state.setLocalVariable("foo",34); - typedValue = state.lookupVariable("foo"); - assertThat(typedValue).isEqualTo(TypedValue.NULL); - - state.setVariable("goo", "hello"); - assertThat(state.lookupLocalVariable("goo")).isNull(); - } - - @Test - @SuppressWarnings("removal") - void localVariableNestedScopes() { - assertThat(state.lookupLocalVariable("foo")).isNull(); - - state.setLocalVariable("foo",12); - assertThat(state.lookupLocalVariable("foo")).isEqualTo(12); - - state.enterScope(null); - // found in upper scope - assertThat(state.lookupLocalVariable("foo")).isEqualTo(12); - - state.setLocalVariable("foo","abc"); - // found in nested scope - assertThat(state.lookupLocalVariable("foo")).isEqualTo("abc"); - - state.exitScope(); - // found in nested scope - assertThat(state.lookupLocalVariable("foo")).isEqualTo(12); - } - @Test void rootContextObject() { assertThat(state.getRootContextObject().getValue().getClass()).isEqualTo(Inventor.class); @@ -159,25 +107,6 @@ class ExpressionStateTests extends AbstractExpressionTests { assertThat(state.getActiveContextObject()).isEqualTo(TypedValue.NULL); } - @Test - @SuppressWarnings("removal") - void populatedNestedScopes() { - assertThat(state.lookupLocalVariable("foo")).isNull(); - - state.enterScope("foo",34); - assertThat(state.lookupLocalVariable("foo")).isEqualTo(34); - - state.enterScope(null); - state.setLocalVariable("foo", 12); - assertThat(state.lookupLocalVariable("foo")).isEqualTo(12); - - state.exitScope(); - assertThat(state.lookupLocalVariable("foo")).isEqualTo(34); - - state.exitScope(); - assertThat(state.lookupLocalVariable("goo")).isNull(); - } - @Test void rootObjectConstructor() { EvaluationContext ctx = TestScenarioCreator.getTestEvaluationContext(); @@ -189,27 +118,6 @@ class ExpressionStateTests extends AbstractExpressionTests { assertThat(stateRoot.getValue()).isEqualTo("i am a string"); } - @Test - @SuppressWarnings("removal") - void populatedNestedScopesMap() { - assertThat(state.lookupLocalVariable("foo")).isNull(); - assertThat(state.lookupLocalVariable("goo")).isNull(); - - state.enterScope(Map.of("foo", 34, "goo", "abc")); - assertThat(state.lookupLocalVariable("foo")).isEqualTo(34); - assertThat(state.lookupLocalVariable("goo")).isEqualTo("abc"); - - state.enterScope(null); - state.setLocalVariable("foo",12); - assertThat(state.lookupLocalVariable("foo")).isEqualTo(12); - assertThat(state.lookupLocalVariable("goo")).isEqualTo("abc"); - - state.exitScope(); - state.exitScope(); - assertThat(state.lookupLocalVariable("foo")).isNull(); - assertThat(state.lookupLocalVariable("goo")).isNull(); - } - @Test void operators() { assertThatExceptionOfType(SpelEvaluationException.class) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AsyncHandlerMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AsyncHandlerMethodReturnValueHandler.java index f6342f6f847..72c85ae9947 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AsyncHandlerMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AsyncHandlerMethodReturnValueHandler.java @@ -50,35 +50,6 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur */ boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType); - /** - * Adapt the asynchronous return value to a - * {@link org.springframework.util.concurrent.ListenableFuture ListenableFuture}. - *

Implementations should consider returning an instance of - * {@link org.springframework.util.concurrent.SettableListenableFuture - * SettableListenableFuture}. Return value handling will then continue when - * the ListenableFuture is completed with either success or error. - *

Note: this method will only be invoked after - * {@link #supportsReturnType(org.springframework.core.MethodParameter)} - * is called and it returns {@code true}. - * @param returnValue the value returned from the handler method - * @param returnType the type of the return value - * @return the resulting ListenableFuture, or {@code null} in which case - * no further handling will be performed - * @deprecated as of 6.0, in favor of - * {@link #toCompletableFuture(Object, MethodParameter)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - @Nullable - default org.springframework.util.concurrent.ListenableFuture toListenableFuture( - Object returnValue, MethodParameter returnType) { - - CompletableFuture result = toCompletableFuture(returnValue, returnType); - return (result != null ? - new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>(result) : - null); - } - /** * Adapt the asynchronous return value to a {@link CompletableFuture}. *

Return value handling will then continue when diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/ListenableFutureReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/ListenableFutureReturnValueHandler.java deleted file mode 100644 index 93aeb5952cd..00000000000 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/ListenableFutureReturnValueHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.messaging.handler.invocation; - -import java.util.concurrent.CompletableFuture; - -import org.springframework.core.MethodParameter; - -/** - * Support for {@link org.springframework.util.concurrent.ListenableFuture} as a return value type. - * - * @author Sebastien Deleuze - * @since 4.2 - * @deprecated as of 6.0, in favor of {@link CompletableFutureReturnValueHandler} - */ -@Deprecated(since = "6.0", forRemoval = true) -@SuppressWarnings("removal") -public class ListenableFutureReturnValueHandler extends AbstractAsyncReturnValueHandler { - - @Override - public boolean supportsReturnType(MethodParameter returnType) { - return org.springframework.util.concurrent.ListenableFuture.class.isAssignableFrom(returnType.getParameterType()); - } - - @Override - public org.springframework.util.concurrent.ListenableFuture toListenableFuture(Object returnValue, MethodParameter returnType) { - return (org.springframework.util.concurrent.ListenableFuture) returnValue; - } - - @Override - public CompletableFuture toCompletableFuture(Object returnValue, MethodParameter returnType) { - return ((org.springframework.util.concurrent.ListenableFuture) returnValue).completable(); - } - -} diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java index 41ecfb1730e..caefa70ac49 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java @@ -344,13 +344,11 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan } @Override - @SuppressWarnings("removal") protected List initReturnValueHandlers() { List handlers = new ArrayList<>(); // Single-purpose return value types - handlers.add(new org.springframework.messaging.handler.invocation.ListenableFutureReturnValueHandler()); handlers.add(new CompletableFutureReturnValueHandler()); if (reactorPresent) { handlers.add(new ReactiveReturnValueHandler()); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ConnectionHandlingStompSession.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ConnectionHandlingStompSession.java index 40faa0bcd59..77befefeb96 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ConnectionHandlingStompSession.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ConnectionHandlingStompSession.java @@ -31,17 +31,6 @@ import java.util.concurrent.CompletableFuture; */ public interface ConnectionHandlingStompSession extends StompSession, StompTcpConnectionHandler { - /** - * Return a future that will complete when the session is ready for use. - * @deprecated as of 6.0, in favor of {@link #getSession()} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - default org.springframework.util.concurrent.ListenableFuture getSessionFuture() { - return new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>( - getSession()); - } - /** * Return a future that will complete when the session is ready for use. * @since 6.0 diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClient.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClient.java index d16ab82b328..e321e19f667 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClient.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/ReactorNettyTcpStompClient.java @@ -89,22 +89,6 @@ public class ReactorNettyTcpStompClient extends StompClientSupport { } - /** - * Connect and notify the given {@link StompSessionHandler} when connected - * on the STOMP level. - * @param handler the handler for the STOMP session - * @return a ListenableFuture for access to the session when ready for use - * @deprecated as of 6.0, in favor of {@link #connectAsync(StompSessionHandler)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - public org.springframework.util.concurrent.ListenableFuture connect( - StompSessionHandler handler) { - - return new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>( - connectAsync(handler)); - } - /** * Connect and notify the given {@link StompSessionHandler} when connected * on the STOMP level. @@ -116,24 +100,6 @@ public class ReactorNettyTcpStompClient extends StompClientSupport { return connectAsync(null, handler); } - /** - * An overloaded version of {@link #connect(StompSessionHandler)} that - * accepts headers to use for the STOMP CONNECT frame. - * @param connectHeaders headers to add to the CONNECT frame - * @param handler the handler for the STOMP session - * @return a ListenableFuture for access to the session when ready for use - * @deprecated as of 6.0, in favor of {@link #connectAsync(StompHeaders, StompSessionHandler)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - public org.springframework.util.concurrent.ListenableFuture connect( - @Nullable StompHeaders connectHeaders, StompSessionHandler handler) { - - ConnectionHandlingStompSession session = createSession(connectHeaders, handler); - this.tcpClient.connectAsync(session); - return session.getSessionFuture(); - } - /** * An overloaded version of {@link #connectAsync(StompSessionHandler)} that * accepts headers to use for the STOMP CONNECT frame. diff --git a/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpConnection.java b/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpConnection.java index 545b1f3d121..c3f1bdccca4 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpConnection.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpConnection.java @@ -30,20 +30,6 @@ import org.springframework.messaging.Message; */ public interface TcpConnection

extends Closeable { - /** - * Send the given message. - * @param message the message - * @return a ListenableFuture that can be used to determine when and if the - * message was successfully sent - * @deprecated as of 6.0, in favor of {@link #sendAsync(Message)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - default org.springframework.util.concurrent.ListenableFuture send(Message

message) { - return new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>( - sendAsync(message)); - } - /** * Send the given message. * @param message the message diff --git a/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpOperations.java b/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpOperations.java index 6ee521358da..d6a7099ab66 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpOperations.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/tcp/TcpOperations.java @@ -27,22 +27,6 @@ import java.util.concurrent.CompletableFuture; */ public interface TcpOperations

{ - /** - * Open a new connection. - * @param connectionHandler a handler to manage the connection - * @return a ListenableFuture that can be used to determine when and if the - * connection is successfully established - * @deprecated as of 6.0, in favor of {@link #connectAsync(TcpConnectionHandler)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - default org.springframework.util.concurrent.ListenableFuture connect( - TcpConnectionHandler

connectionHandler) { - - return new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>( - connectAsync(connectionHandler)); - } - /** * Open a new connection. * @param connectionHandler a handler to manage the connection @@ -52,23 +36,6 @@ public interface TcpOperations

{ */ CompletableFuture connectAsync(TcpConnectionHandler

connectionHandler); - /** - * Open a new connection and a strategy for reconnecting if the connection fails. - * @param connectionHandler a handler to manage the connection - * @param reconnectStrategy a strategy for reconnecting - * @return a ListenableFuture that can be used to determine when and if the - * initial connection is successfully established - * @deprecated as of 6.0, in favor of {@link #connectAsync(TcpConnectionHandler, ReconnectStrategy)} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - default org.springframework.util.concurrent.ListenableFuture connect( - TcpConnectionHandler

connectionHandler, ReconnectStrategy reconnectStrategy) { - - return new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>( - connectAsync(connectionHandler, reconnectStrategy)); - } - /** * Open a new connection and a strategy for reconnecting if the connection fails. * @param connectionHandler a handler to manage the connection @@ -79,18 +46,6 @@ public interface TcpOperations

{ */ CompletableFuture connectAsync(TcpConnectionHandler

connectionHandler, ReconnectStrategy reconnectStrategy); - /** - * Shut down and close any open connections. - * @return a ListenableFuture that can be used to determine when and if the - * connection is successfully closed - * @deprecated as of 6.0, in favor of {@link #shutdownAsync()} - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - default org.springframework.util.concurrent.ListenableFuture shutdown() { - return new org.springframework.util.concurrent.CompletableToListenableFutureAdapter<>(shutdownAsync()); - } - /** * Shut down and close any open connections. * @return a CompletableFuture that can be used to determine when and if the diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandlerTests.java index 532838457aa..7421a10d3c6 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandlerTests.java @@ -273,39 +273,6 @@ public class SimpAnnotationMethodMessageHandlerTests { assertThat(controller.method).isEqualTo("handleFoo"); } - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void listenableFutureSuccess() { - Message emptyMessage = MessageBuilder.withPayload(new byte[0]).build(); - given(this.channel.send(any(Message.class))).willReturn(true); - given(this.converter.toMessage(any(), any(MessageHeaders.class))).willReturn(emptyMessage); - - ListenableFutureController controller = new ListenableFutureController(); - this.messageHandler.registerHandler(controller); - this.messageHandler.setDestinationPrefixes(Arrays.asList("/app1", "/app2/")); - - Message message = createMessage("/app1/listenable-future/success"); - this.messageHandler.handleMessage(message); - - assertThat(controller.future).isNotNull(); - controller.future.run(); - verify(this.converter).toMessage(this.payloadCaptor.capture(), any(MessageHeaders.class)); - assertThat(this.payloadCaptor.getValue()).isEqualTo("foo"); - } - - @Test - void listenableFutureFailure() { - ListenableFutureController controller = new ListenableFutureController(); - this.messageHandler.registerHandler(controller); - this.messageHandler.setDestinationPrefixes(Arrays.asList("/app1", "/app2/")); - - Message message = createMessage("/app1/listenable-future/failure"); - this.messageHandler.handleMessage(message); - - controller.future.run(); - assertThat(controller.exceptionCaught).isTrue(); - } - @Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void completableFutureSuccess() { @@ -569,36 +536,6 @@ public class SimpAnnotationMethodMessageHandlerTests { } - @Controller - @MessageMapping("listenable-future") - @SuppressWarnings({"deprecation", "removal"}) - private static class ListenableFutureController { - - org.springframework.util.concurrent.ListenableFutureTask future; - - boolean exceptionCaught = false; - - @MessageMapping("success") - public org.springframework.util.concurrent.ListenableFutureTask handleListenableFuture() { - this.future = new org.springframework.util.concurrent.ListenableFutureTask<>(() -> "foo"); - return this.future; - } - - @MessageMapping("failure") - public org.springframework.util.concurrent.ListenableFutureTask handleListenableFutureException() { - this.future = new org.springframework.util.concurrent.ListenableFutureTask<>(() -> { - throw new IllegalStateException(); - }); - return this.future; - } - - @MessageExceptionHandler(IllegalStateException.class) - public void handleValidationException() { - this.exceptionCaught = true; - } - } - - @Controller private static class CompletableFutureController { diff --git a/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java b/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java index 00771118bed..f3e8841e650 100644 --- a/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java +++ b/spring-test/src/main/java/org/springframework/test/util/JsonPathExpectationsHelper.java @@ -82,18 +82,6 @@ public class JsonPathExpectationsHelper { this.configuration = (configuration != null) ? configuration : Configuration.defaultConfiguration(); } - /** - * Construct a new {@code JsonPathExpectationsHelper}. - * @param expression the {@link JsonPath} expression; never {@code null} or empty - * @param args arguments to parameterize the {@code JsonPath} expression with, - * using formatting specifiers defined in {@link String#format(String, Object...)} - * @deprecated in favor of calling {@link String#formatted(Object...)} upfront - */ - @Deprecated(since = "6.2", forRemoval = true) - public JsonPathExpectationsHelper(String expression, Object... args) { - this(expression.formatted(args), (Configuration) null); - } - /** * Evaluate the JSON path expression against the supplied {@code content} diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java index 5b8597a68ec..ad11d715a4b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java @@ -711,13 +711,6 @@ class DefaultWebTestClient implements WebTestClient { JsonPathConfigurationProvider.getConfiguration(this.jsonEncoderDecoder)); } - @Override - @SuppressWarnings("removal") - public JsonPathAssertions jsonPath(String expression, Object... args) { - Assert.hasText(expression, "expression must not be null or empty"); - return jsonPath(expression.formatted(args)); - } - @Override public XpathAssertions xpath(String expression, @Nullable Map namespaces, Object... args) { return new XpathAssertions(this, expression, namespaces, args); diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java index 881b7c0654a..554fddfccbb 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java @@ -176,16 +176,6 @@ public class ExchangeResult { return this.response.getStatusCode(); } - /** - * Return the HTTP status code as an integer. - * @since 5.1.10 - * @deprecated in favor of {@link #getStatus()}, for removal in 7.0 - */ - @Deprecated(since = "6.0", forRemoval = true) - public int getRawStatusCode() { - return getStatus().value(); - } - /** * Return the response headers received from the server. */ diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/JsonPathAssertions.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/JsonPathAssertions.java index d761575ac83..6881a799bf5 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/JsonPathAssertions.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/JsonPathAssertions.java @@ -161,17 +161,6 @@ public class JsonPathAssertions { return this.bodySpec; } - /** - * Delegates to {@link JsonPathExpectationsHelper#assertValue(String, Matcher, Class)}. - * @since 5.1 - * @deprecated in favor of {@link #value(Class, Matcher)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public WebTestClient.BodyContentSpec value(Matcher matcher, Class targetType) { - this.pathHelper.assertValue(this.content, matcher, targetType); - return this.bodySpec; - } - /** * Delegates to {@link JsonPathExpectationsHelper#assertValue(String, Matcher, ParameterizedTypeReference)}. * @since 6.2 @@ -202,16 +191,6 @@ public class JsonPathAssertions { return this.bodySpec; } - /** - * Consume the result of the JSONPath evaluation and provide a target class. - * @since 5.1 - * @deprecated in favor of {@link #value(Class, Consumer)} - */ - @Deprecated(since = "6.2", forRemoval = true) - public WebTestClient.BodyContentSpec value(Consumer consumer, Class targetType) { - return value(targetType, consumer); - } - /** * Consume the result of the JSONPath evaluation and provide a parameterized type. * @since 6.2 diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index 49999e35223..8d766d001c7 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -1075,19 +1075,6 @@ public interface WebTestClient { */ JsonPathAssertions jsonPath(String expression); - /** - * Access to response body assertions using a - * JsonPath expression - * to inspect a specific subset of the body. - *

The JSON path expression can be a parameterized string using - * formatting specifiers as defined in {@link String#format}. - * @param expression the JsonPath expression - * @param args arguments to parameterize the expression - * @deprecated in favor of calling {@link String#formatted(Object...)} upfront - */ - @Deprecated(since = "6.2", forRemoval = true) - JsonPathAssertions jsonPath(String expression, Object... args); - /** * Access to response body assertions using an XPath expression to * inspect a specific subset of the body. diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java index 29c8367c945..b7ebd65934a 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/AsyncTests.java @@ -117,16 +117,6 @@ class AsyncTests { .expectBody(String.class).isEqualTo("Delayed Error"); } - @Test - void listenableFuture() { - this.testClient.get() - .uri("/1?listenableFuture=true") - .exchange() - .expectStatus().isOk() - .expectHeader().contentType(MediaType.APPLICATION_JSON) - .expectBody().json("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"); - } - @Test void completableFutureWithImmediateValue() { this.testClient.get() @@ -193,15 +183,6 @@ class AsyncTests { return result; } - @GetMapping(params = "listenableFuture") - @SuppressWarnings({ "deprecation", "removal" }) - org.springframework.util.concurrent.ListenableFuture getListenableFuture() { - org.springframework.util.concurrent.ListenableFutureTask futureTask = - new org.springframework.util.concurrent.ListenableFutureTask<>(() -> new Person("Joe")); - delay(100, futureTask); - return futureTask; - } - @GetMapping(params = "completableFutureWithImmediateValue") CompletableFuture getCompletableFutureWithImmediateValue() { CompletableFuture future = new CompletableFuture<>(); diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java index dd70f74d9b0..ee2841538c5 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java @@ -144,18 +144,6 @@ class AsyncTests { .andExpect(content().string("Delayed Error")); } - @Test - void listenableFuture() throws Exception { - MvcResult mvcResult = this.mockMvc.perform(get("/1").param("listenableFuture", "true")) - .andExpect(request().asyncStarted()) - .andReturn(); - - this.mockMvc.perform(asyncDispatch(mvcResult)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); - } - @Test // SPR-12597 void completableFutureWithImmediateValue() throws Exception { MvcResult mvcResult = this.mockMvc.perform(get("/1").param("completableFutureWithImmediateValue", "true")) @@ -245,13 +233,6 @@ class AsyncTests { .hasStatus5xxServerError().hasBodyTextEqualTo("Delayed Error"); } - @Test - void listenableFuture() { - assertThat(this.mockMvc.get().uri("/1").param("listenableFuture", "true")) - .hasStatusOk().hasContentTypeCompatibleWith(MediaType.APPLICATION_JSON) - .hasBodyTextEqualTo("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"); - } - @Test // SPR-12597 void completableFutureWithImmediateValue() { assertThat(this.mockMvc.get().uri("/1").param("completableFutureWithImmediateValue", "true")) @@ -333,15 +314,6 @@ class AsyncTests { return result; } - @RequestMapping(params = "listenableFuture") - @SuppressWarnings({"deprecation", "removal"}) - org.springframework.util.concurrent.ListenableFuture getListenableFuture() { - org.springframework.util.concurrent.ListenableFutureTask futureTask = - new org.springframework.util.concurrent.ListenableFutureTask<>(() -> new Person("Joe")); - delay(100, futureTask); - return futureTask; - } - @RequestMapping(params = "completableFutureWithImmediateValue") CompletableFuture getCompletableFutureWithImmediateValue() { CompletableFuture future = new CompletableFuture<>(); diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/GenericReactiveTransaction.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/GenericReactiveTransaction.java index f4c9602a1c6..0cf7a5833d2 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/GenericReactiveTransaction.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/GenericReactiveTransaction.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,13 +96,6 @@ public class GenericReactiveTransaction implements ReactiveTransaction { this.suspendedResources = suspendedResources; } - @Deprecated(since = "6.1", forRemoval = true) - public GenericReactiveTransaction(@Nullable Object transaction, boolean newTransaction, - boolean newSynchronization, boolean readOnly, boolean debug, @Nullable Object suspendedResources) { - - this(null, transaction, newTransaction, newSynchronization, false, readOnly, debug, suspendedResources); - } - @Override public String getTransactionName() { diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionStatus.java b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionStatus.java index 5b92724b5e2..1d71e544d43 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionStatus.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionStatus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,13 +102,6 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus { this.suspendedResources = suspendedResources; } - @Deprecated(since = "6.1", forRemoval = true) - public DefaultTransactionStatus(@Nullable Object transaction, boolean newTransaction, - boolean newSynchronization, boolean readOnly, boolean debug, @Nullable Object suspendedResources) { - - this(null, transaction, newTransaction, newSynchronization, false, readOnly, debug, suspendedResources); - } - @Override public String getTransactionName() { diff --git a/spring-web/spring-web.gradle b/spring-web/spring-web.gradle index 80fb8fe5b5c..b107f41a0bf 100644 --- a/spring-web/spring-web.gradle +++ b/spring-web/spring-web.gradle @@ -20,7 +20,6 @@ dependencies { optional("com.google.code.gson:gson") optional("com.google.protobuf:protobuf-java-util") optional("com.rometools:rome") - optional("com.squareup.okhttp3:okhttp") optional("io.micrometer:context-propagation") optional("io.netty:netty-buffer") optional("io.netty:netty-handler") diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 5d895e4a368..4cd56579cdf 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -1961,21 +1961,6 @@ public class HttpHeaders implements MultiValueMap, Serializable return (headers instanceof ReadOnlyHttpHeaders ? headers : new ReadOnlyHttpHeaders(headers.headers)); } - /** - * Remove any read-only wrapper that may have been previously applied around - * the given headers via {@link #readOnlyHttpHeaders(HttpHeaders)}. - *

Once the writable instance is mutated, the read-only instance is likely - * to be out of sync and should be discarded. - * @param headers the headers to expose - * @return a writable variant of the headers, or the original headers as-is - * @since 5.1.1 - * @deprecated as of 6.2 in favor of {@link #HttpHeaders(MultiValueMap)}. - */ - @Deprecated(since = "6.2", forRemoval = true) - public static HttpHeaders writableHttpHeaders(HttpHeaders headers) { - return new HttpHeaders(headers); - } - /** * Helps to format HTTP header values, as HTTP header values themselves can * contain comma-separated values, can become confusing with regular diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index ff27cb0ea37..308d7c4346d 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -22,7 +22,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -100,23 +99,6 @@ public class MediaType extends MimeType implements Serializable { */ public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded"; - /** - * Public constant media type for {@code application/graphql+json}. - * @since 5.3.19 - * @see GraphQL over HTTP spec change - * @deprecated as of 6.0.3, in favor of {@link MediaType#APPLICATION_GRAPHQL_RESPONSE} - */ - @Deprecated(since = "6.0.3", forRemoval = true) - public static final MediaType APPLICATION_GRAPHQL; - - /** - * A String equivalent of {@link MediaType#APPLICATION_GRAPHQL}. - * @since 5.3.19 - * @deprecated as of 6.0.3, in favor of {@link MediaType#APPLICATION_GRAPHQL_RESPONSE_VALUE} - */ - @Deprecated(since = "6.0.3", forRemoval = true) - public static final String APPLICATION_GRAPHQL_VALUE = "application/graphql+json"; - /** * Public constant media type for {@code application/graphql-response+json}. * @since 6.0.3 @@ -456,7 +438,6 @@ public class MediaType extends MimeType implements Serializable { APPLICATION_ATOM_XML = new MediaType("application", "atom+xml"); APPLICATION_CBOR = new MediaType("application", "cbor"); APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded"); - APPLICATION_GRAPHQL = new MediaType("application", "graphql+json"); APPLICATION_GRAPHQL_RESPONSE = new MediaType("application", "graphql-response+json"); APPLICATION_JSON = new MediaType("application", "json"); APPLICATION_JSON_UTF8 = new MediaType("application", "json", StandardCharsets.UTF_8); @@ -847,141 +828,4 @@ public class MediaType extends MimeType implements Serializable { return MimeTypeUtils.toString(mediaTypes); } - /** - * Sorts the given list of {@code MediaType} objects by specificity. - *

Given two media types: - *

    - *
  1. if either media type has a {@linkplain #isWildcardType() wildcard type}, then the media type without the - * wildcard is ordered before the other.
  2. - *
  3. if the two media types have different {@linkplain #getType() types}, then they are considered equal and - * remain their current order.
  4. - *
  5. if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype}, then the media type without - * the wildcard is sorted before the other.
  6. - *
  7. if the two media types have different {@linkplain #getSubtype() subtypes}, then they are considered equal - * and remain their current order.
  8. - *
  9. if the two media types have different {@linkplain #getQualityValue() quality value}, then the media type - * with the highest quality value is ordered before the other.
  10. - *
  11. if the two media types have a different amount of {@linkplain #getParameter(String) parameters}, then the - * media type with the most parameters is ordered before the other.
  12. - *
- *

For example: - *

audio/basic < audio/* < */*
- *
audio/* < audio/*;q=0.7; audio/*;q=0.3
- *
audio/basic;level=1 < audio/basic
- *
audio/basic == text/html
- *
audio/basic == audio/wave
- * @param mediaTypes the list of media types to be sorted - * @deprecated As of 6.0, in favor of {@link MimeTypeUtils#sortBySpecificity(List)} - */ - @Deprecated(since = "6.0", forRemoval = true) - public static void sortBySpecificity(List mediaTypes) { - Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); - if (mediaTypes.size() > 1) { - mediaTypes.sort(SPECIFICITY_COMPARATOR); - } - } - - /** - * Sorts the given list of {@code MediaType} objects by quality value. - *

Given two media types: - *

    - *
  1. if the two media types have different {@linkplain #getQualityValue() quality value}, then the media type - * with the highest quality value is ordered before the other.
  2. - *
  3. if either media type has a {@linkplain #isWildcardType() wildcard type}, then the media type without the - * wildcard is ordered before the other.
  4. - *
  5. if the two media types have different {@linkplain #getType() types}, then they are considered equal and - * remain their current order.
  6. - *
  7. if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype}, then the media type without - * the wildcard is sorted before the other.
  8. - *
  9. if the two media types have different {@linkplain #getSubtype() subtypes}, then they are considered equal - * and remain their current order.
  10. - *
  11. if the two media types have a different amount of {@linkplain #getParameter(String) parameters}, then the - * media type with the most parameters is ordered before the other.
  12. - *
- * @param mediaTypes the list of media types to be sorted - * @see #getQualityValue() - * @deprecated As of 6.0, with no direct replacement - */ - @Deprecated(since = "6.0", forRemoval = true) - public static void sortByQualityValue(List mediaTypes) { - Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); - if (mediaTypes.size() > 1) { - mediaTypes.sort(QUALITY_VALUE_COMPARATOR); - } - } - - /** - * Sorts the given list of {@code MediaType} objects by specificity as the - * primary criteria and quality value the secondary. - * @deprecated As of 6.0, in favor of {@link MimeTypeUtils#sortBySpecificity(List)} - */ - @Deprecated(since = "6.0") - public static void sortBySpecificityAndQuality(List mediaTypes) { - Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); - if (mediaTypes.size() > 1) { - mediaTypes.sort(MediaType.SPECIFICITY_COMPARATOR.thenComparing(MediaType.QUALITY_VALUE_COMPARATOR)); - } - } - - - /** - * Comparator used by {@link #sortByQualityValue(List)}. - * @deprecated As of 6.0, with no direct replacement - */ - @Deprecated(since = "6.0", forRemoval = true) - public static final Comparator QUALITY_VALUE_COMPARATOR = (mediaType1, mediaType2) -> { - double quality1 = mediaType1.getQualityValue(); - double quality2 = mediaType2.getQualityValue(); - int qualityComparison = Double.compare(quality2, quality1); - if (qualityComparison != 0) { - return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3 - } - else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* < audio/* - return 1; - } - else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* - return -1; - } - else if (!mediaType1.getType().equals(mediaType2.getType())) { // audio/basic == text/html - return 0; - } - else { // mediaType1.getType().equals(mediaType2.getType()) - if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic - return 1; - } - else if (mediaType2.isWildcardSubtype() && !mediaType1.isWildcardSubtype()) { // audio/basic > audio/* - return -1; - } - else if (!mediaType1.getSubtype().equals(mediaType2.getSubtype())) { // audio/basic == audio/wave - return 0; - } - else { - int paramsSize1 = mediaType1.getParameters().size(); - int paramsSize2 = mediaType2.getParameters().size(); - return Integer.compare(paramsSize2, paramsSize1); // audio/basic;level=1 < audio/basic - } - } - }; - - - /** - * Comparator used by {@link #sortBySpecificity(List)}. - * @deprecated As of 6.0, with no direct replacement - */ - @Deprecated(since = "6.0", forRemoval = true) - @SuppressWarnings("removal") - public static final Comparator SPECIFICITY_COMPARATOR = new SpecificityComparator<>() { - - @Override - protected int compareParameters(MediaType mediaType1, MediaType mediaType2) { - double quality1 = mediaType1.getQualityValue(); - double quality2 = mediaType2.getQualityValue(); - int qualityComparison = Double.compare(quality2, quality1); - if (qualityComparison != 0) { - return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3 - } - return super.compareParameters(mediaType1, mediaType2); - } - }; - } diff --git a/spring-web/src/main/java/org/springframework/http/client/ClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/ClientHttpResponse.java index b4b90443d4a..455f2c12f54 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/ClientHttpResponse.java @@ -42,19 +42,6 @@ public interface ClientHttpResponse extends HttpInputMessage, Closeable { */ HttpStatusCode getStatusCode() throws IOException; - /** - * Get the HTTP status code as an integer. - * @return the HTTP status as an integer value - * @throws IOException in case of I/O errors - * @since 3.1.1 - * @see #getStatusCode() - * @deprecated in favor of {@link #getStatusCode()}, for removal in 7.0 - */ - @Deprecated(since = "6.0", forRemoval = true) - default int getRawStatusCode() throws IOException { - return getStatusCode().value(); - } - /** * Get the HTTP status text of the response. * @return the HTTP status text diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java index 6d62a8ffbb3..3f3825c62f0 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java @@ -209,18 +209,6 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest this.readTimeout = readTimeout.toMillis(); } - /** - * Indicates whether this request factory should buffer the request body internally. - *

Default is {@code true}. When sending large amounts of data via POST or PUT, it is - * recommended to change this property to {@code false}, so as not to run out of memory. - * @since 4.0 - * @deprecated since 6.1 requests are never buffered, as if this property is {@code false} - */ - @Deprecated(since = "6.1", forRemoval = true) - public void setBufferRequestBody(boolean bufferRequestBody) { - // no-op - } - /** * Configure a factory to pre-create the {@link HttpContext} for each request. *

This may be useful for example in mutual TLS authentication where a diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequest.java deleted file mode 100644 index f6448d92448..00000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; - -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okio.BufferedSink; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; - -/** - * {@link ClientHttpRequest} implementation based on OkHttp 3.x. - * - *

Created via the {@link OkHttp3ClientHttpRequestFactory}. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @author Roy Clarkson - * @since 4.3 - * @deprecated since 6.1, in favor of other HTTP client libraries; - * scheduled for removal in 7.0 - */ -@Deprecated(since = "6.1", forRemoval = true) -class OkHttp3ClientHttpRequest extends AbstractStreamingClientHttpRequest { - - private final OkHttpClient client; - - private final URI uri; - - private final HttpMethod method; - - - public OkHttp3ClientHttpRequest(OkHttpClient client, URI uri, HttpMethod method) { - this.client = client; - this.uri = uri; - this.method = method; - } - - - @Override - public HttpMethod getMethod() { - return this.method; - } - - @Override - public URI getURI() { - return this.uri; - } - - @Override - @SuppressWarnings("removal") - protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException { - - RequestBody requestBody; - if (body != null) { - requestBody = new BodyRequestBody(headers, body); - } - else if (okhttp3.internal.http.HttpMethod.requiresRequestBody(getMethod().name())) { - String header = headers.getFirst(HttpHeaders.CONTENT_TYPE); - MediaType contentType = (header != null) ? MediaType.parse(header) : null; - requestBody = RequestBody.create(contentType, new byte[0]); - } - else { - requestBody = null; - } - Request.Builder builder = new Request.Builder() - .url(this.uri.toURL()); - builder.method(this.method.name(), requestBody); - headers.forEach((headerName, headerValues) -> { - for (String headerValue : headerValues) { - builder.addHeader(headerName, headerValue); - } - }); - Request request = builder.build(); - return new OkHttp3ClientHttpResponse(this.client.newCall(request).execute()); - } - - - private static class BodyRequestBody extends RequestBody { - - private final HttpHeaders headers; - - private final Body body; - - - public BodyRequestBody(HttpHeaders headers, Body body) { - this.headers = headers; - this.body = body; - } - - @Override - public long contentLength() { - return this.headers.getContentLength(); - } - - @Nullable - @Override - public MediaType contentType() { - String contentType = this.headers.getFirst(HttpHeaders.CONTENT_TYPE); - if (StringUtils.hasText(contentType)) { - return MediaType.parse(contentType); - } - else { - return null; - } - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - this.body.writeTo(sink.outputStream()); - } - - @Override - public boolean isOneShot() { - return !this.body.repeatable(); - } - } - - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java deleted file mode 100644 index 6a9a637e339..00000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactory.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.net.URI; -import java.time.Duration; -import java.util.concurrent.TimeUnit; - -import okhttp3.Cache; -import okhttp3.OkHttpClient; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.http.HttpMethod; -import org.springframework.util.Assert; - -/** - * {@link ClientHttpRequestFactory} implementation that uses - * OkHttp 3.x to create requests. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @author Roy Clarkson - * @since 4.3 - * @deprecated since 6.1, in favor of other {@link ClientHttpRequestFactory} implementations; - * scheduled for removal in 7.0 - */ -@Deprecated(since = "6.1", forRemoval = true) -public class OkHttp3ClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean { - - private OkHttpClient client; - - private final boolean defaultClient; - - - /** - * Create a factory with a default {@link OkHttpClient} instance. - */ - public OkHttp3ClientHttpRequestFactory() { - this.client = new OkHttpClient(); - this.defaultClient = true; - } - - /** - * Create a factory with the given {@link OkHttpClient} instance. - * @param client the client to use - */ - public OkHttp3ClientHttpRequestFactory(OkHttpClient client) { - Assert.notNull(client, "OkHttpClient must not be null"); - this.client = client; - this.defaultClient = false; - } - - - /** - * Set the underlying read timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - */ - public void setReadTimeout(int readTimeout) { - this.client = this.client.newBuilder() - .readTimeout(readTimeout, TimeUnit.MILLISECONDS) - .build(); - } - - /** - * Set the underlying read timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - * @since 6.1 - */ - public void setReadTimeout(Duration readTimeout) { - this.client = this.client.newBuilder() - .readTimeout(readTimeout) - .build(); - } - - /** - * Set the underlying write timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - */ - public void setWriteTimeout(int writeTimeout) { - this.client = this.client.newBuilder() - .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS) - .build(); - } - - /** - * Set the underlying write timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - * @since 6.1 - */ - public void setWriteTimeout(Duration writeTimeout) { - this.client = this.client.newBuilder() - .writeTimeout(writeTimeout) - .build(); - } - - /** - * Set the underlying connect timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - */ - public void setConnectTimeout(int connectTimeout) { - this.client = this.client.newBuilder() - .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) - .build(); - } - - /** - * Set the underlying connect timeout in milliseconds. - * A value of 0 specifies an infinite timeout. - * @since 6.1 - */ - public void setConnectTimeout(Duration connectTimeout) { - this.client = this.client.newBuilder() - .connectTimeout(connectTimeout) - .build(); - } - - - @Override - @SuppressWarnings("removal") - public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - return new OkHttp3ClientHttpRequest(this.client, uri, httpMethod); - } - - - @Override - public void destroy() throws IOException { - if (this.defaultClient) { - // Clean up the client if we created it in the constructor - Cache cache = this.client.cache(); - if (cache != null) { - cache.close(); - } - this.client.dispatcher().executorService().shutdown(); - this.client.connectionPool().evictAll(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpResponse.java deleted file mode 100644 index 1e233e82ad5..00000000000 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttp3ClientHttpResponse.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.io.IOException; -import java.io.InputStream; - -import okhttp3.Response; -import okhttp3.ResponseBody; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatusCode; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * {@link ClientHttpResponse} implementation based on OkHttp 3.x. - * - * @author Luciano Leggieri - * @author Arjen Poutsma - * @author Roy Clarkson - * @since 4.3 - * @deprecated since 6.1, in favor of other HTTP client libraries; - * scheduled for removal in 7.0 - */ -@Deprecated(since = "6.1", forRemoval = true) -class OkHttp3ClientHttpResponse implements ClientHttpResponse { - - private final Response response; - - @Nullable - private volatile HttpHeaders headers; - - - public OkHttp3ClientHttpResponse(Response response) { - Assert.notNull(response, "Response must not be null"); - this.response = response; - } - - - @Override - public HttpStatusCode getStatusCode() throws IOException { - return HttpStatusCode.valueOf(this.response.code()); - } - - @Override - public String getStatusText() { - return this.response.message(); - } - - @Override - public InputStream getBody() throws IOException { - ResponseBody body = this.response.body(); - return (body != null ? body.byteStream() : InputStream.nullInputStream()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = this.headers; - if (headers == null) { - headers = new HttpHeaders(); - for (String headerName : this.response.headers().names()) { - for (String headerValue : this.response.headers(headerName)) { - headers.add(headerName, headerValue); - } - } - this.headers = headers; - } - return headers; - } - - @Override - public void close() { - ResponseBody body = this.response.body(); - if (body != null) { - body.close(); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequest.java index feddda57a76..b55dfee5601 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequest.java @@ -81,24 +81,6 @@ final class ReactorClientHttpRequest extends AbstractStreamingClientHttpRequest this.exchangeTimeout = exchangeTimeout; } - /** - * Original constructor with timeout values. - * @deprecated without a replacement; readTimeout is now applied to the - * underlying client via {@link HttpClient#responseTimeout(Duration)}, and the - * value passed here is not used; exchangeTimeout is deprecated and superseded - * by Reactor Netty timeout configuration, but applied if set. - */ - @Deprecated(since = "6.2", forRemoval = true) - public ReactorClientHttpRequest( - HttpClient httpClient, URI uri, HttpMethod method, - @Nullable Duration exchangeTimeout, @Nullable Duration readTimeout) { - - this.httpClient = httpClient; - this.method = method; - this.uri = uri; - this.exchangeTimeout = exchangeTimeout; - } - @Override public HttpMethod getMethod() { diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequestFactory.java index f3366497cc3..63cfc19ffac 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpRequestFactory.java @@ -180,36 +180,6 @@ public class ReactorClientHttpRequestFactory implements ClientHttpRequestFactory setReadTimeout(Duration.ofMillis(readTimeout)); } - /** - * Set the timeout for the HTTP exchange in milliseconds. - *

By default, as of 6.2 this is no longer set. - * @see #setConnectTimeout(int) - * @see #setReadTimeout(Duration) - * @see Timeout Configuration - * @deprecated as of 6.2 and no longer set by default (previously 5 seconds) - * in favor of using Reactor Netty HttpClient timeout configuration. - */ - @Deprecated(since = "6.2", forRemoval = true) - public void setExchangeTimeout(long exchangeTimeout) { - Assert.isTrue(exchangeTimeout > 0, "Timeout must be a positive value"); - this.exchangeTimeout = Duration.ofMillis(exchangeTimeout); - } - - /** - * Variant of {@link #setExchangeTimeout(long)} with a Duration value. - *

By default, as of 6.2 this is no longer set. - * @see #setConnectTimeout(int) - * @see #setReadTimeout(Duration) - * @see Timeout Configuration - * @deprecated as of 6.2 and no longer set by default (previously 5 seconds) - * in favor of using Reactor Netty HttpClient timeout configuration. - */ - @Deprecated(since = "6.2", forRemoval = true) - public void setExchangeTimeout(Duration exchangeTimeout) { - Assert.notNull(exchangeTimeout, "ExchangeTimeout must not be null"); - setExchangeTimeout((int) exchangeTimeout.toMillis()); - } - @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpResponse.java index b83395a163b..4f92c099793 100644 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/ReactorClientHttpResponse.java @@ -18,12 +18,10 @@ package org.springframework.http.client; import java.io.IOException; import java.io.InputStream; -import java.time.Duration; import io.netty.buffer.ByteBuf; import org.reactivestreams.FlowAdapters; import reactor.netty.Connection; -import reactor.netty.http.client.HttpClient; import reactor.netty.http.client.HttpClientResponse; import org.springframework.http.HttpHeaders; @@ -64,21 +62,6 @@ final class ReactorClientHttpResponse implements ClientHttpResponse { new Netty4HeadersAdapter(response.responseHeaders())); } - /** - * Original constructor. - * @deprecated without a replacement; readTimeout is now applied to the - * underlying client via {@link HttpClient#responseTimeout(Duration)}, and the - * value passed here is not used. - */ - @Deprecated(since = "6.2", forRemoval = true) - public ReactorClientHttpResponse( - HttpClientResponse response, Connection connection, @Nullable Duration readTimeout) { - - this.response = response; - this.connection = connection; - this.headers = HttpHeaders.readOnlyHttpHeaders(new Netty4HeadersAdapter(response.responseHeaders())); - } - @Override public HttpStatusCode getStatusCode() { diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequestFactory.java deleted file mode 100644 index a116c071385..00000000000 --- a/spring-web/src/main/java/org/springframework/http/client/ReactorNettyClientRequestFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import java.util.function.Function; - -import reactor.netty.http.client.HttpClient; - -/** - * Reactor-Netty implementation of {@link ClientHttpRequestFactory}. - * - * @author Arjen Poutsma - * @author Juergen Hoeller - * @since 6.1 - * @deprecated in favor of the renamed {@link ReactorClientHttpRequestFactory} - */ -@Deprecated(since = "6.2", forRemoval = true) -public class ReactorNettyClientRequestFactory extends ReactorClientHttpRequestFactory { - - /** - * Superseded by {@link ReactorClientHttpRequestFactory}. - * @see ReactorClientHttpRequestFactory#ReactorClientHttpRequestFactory() - */ - public ReactorNettyClientRequestFactory() { - super(); - } - - /** - * Superseded by {@link ReactorClientHttpRequestFactory}. - * @see ReactorClientHttpRequestFactory#ReactorClientHttpRequestFactory(HttpClient) - */ - public ReactorNettyClientRequestFactory(HttpClient httpClient) { - super(httpClient); - } - - /** - * Superseded by {@link ReactorClientHttpRequestFactory}. - * @see ReactorClientHttpRequestFactory#ReactorClientHttpRequestFactory(ReactorResourceFactory, Function) - */ - public ReactorNettyClientRequestFactory(ReactorResourceFactory resourceFactory, Function mapper) { - super(resourceFactory, mapper); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index ec2b075bd53..995f73c9e23 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,24 +59,6 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory this.proxy = proxy; } - /** - * Indicate whether this request factory should buffer the - * {@linkplain ClientHttpRequest#getBody() request body} internally. - *

Default is {@code true}. When sending large amounts of data via POST or PUT, - * it is recommended to change this property to {@code false}, so as not to run - * out of memory. This will result in a {@link ClientHttpRequest} that either - * streams directly to the underlying {@link HttpURLConnection} (if the - * {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} - * is known in advance), or that will use "Chunked transfer encoding" - * (if the {@code Content-Length} is not known in advance). - * @see #setChunkSize(int) - * @see HttpURLConnection#setFixedLengthStreamingMode(int) - * @deprecated since 6.1 requests are never buffered, as if this property is {@code false} - */ - @Deprecated(since = "6.1", forRemoval = true) - public void setBufferRequestBody(boolean bufferRequestBody) { - } - /** * Set the number of bytes to write in each chunk when not buffering request * bodies locally. @@ -134,20 +116,6 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory this.readTimeout = (int) readTimeout.toMillis(); } - /** - * Set if the underlying URLConnection can be set to 'output streaming' mode. - * Default is {@code true}. - *

When output streaming is enabled, authentication and redirection cannot be handled automatically. - * If output streaming is disabled, the {@link HttpURLConnection#setFixedLengthStreamingMode} and - * {@link HttpURLConnection#setChunkedStreamingMode} methods of the underlying connection will never - * be called. - * @param outputStreaming if output streaming is enabled - * @deprecated as of 6.1 requests are always streamed, as if this property is {@code true} - */ - @Deprecated(since = "6.1", forRemoval = true) - public void setOutputStreaming(boolean outputStreaming) { - } - @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/ClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/reactive/ClientHttpResponse.java index f031558d9ba..23711637ccd 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/ClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/ClientHttpResponse.java @@ -46,18 +46,6 @@ public interface ClientHttpResponse extends ReactiveHttpInputMessage { */ HttpStatusCode getStatusCode(); - /** - * Return the HTTP status code as an integer. - * @return the HTTP status as an integer value - * @since 5.0.6 - * @see #getStatusCode() - * @deprecated in favor of {@link #getStatusCode()}, for removal in 7.0 - */ - @Deprecated(since = "6.0", forRemoval = true) - default int getRawStatusCode() { - return getStatusCode().value(); - } - /** * Return a read-only map of response cookies received from the server. */ diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorNetty2ServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorNetty2ServerHttpResponse.java index 0e8c6c68b1d..3d89eaad7a4 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorNetty2ServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorNetty2ServerHttpResponse.java @@ -76,14 +76,6 @@ class ReactorNetty2ServerHttpResponse extends AbstractServerHttpResponse impleme return (status != null ? status : HttpStatusCode.valueOf(this.response.status().code())); } - @Override - @Deprecated - @SuppressWarnings("removal") - public Integer getRawStatusCode() { - Integer status = super.getRawStatusCode(); - return (status != null ? status : this.response.status().code()); - } - @Override protected void applyStatusCode() { HttpStatusCode status = super.getStatusCode(); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java index 359629ff75d..d0f8cea29ef 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java @@ -75,14 +75,6 @@ class ReactorServerHttpResponse extends AbstractServerHttpResponse implements Ze return (status != null ? status : HttpStatusCode.valueOf(this.response.status().code())); } - @Override - @Deprecated - @SuppressWarnings("removal") - public Integer getRawStatusCode() { - Integer status = super.getRawStatusCode(); - return (status != null ? status : this.response.status().code()); - } - @Override protected void applyStatusCode() { HttpStatusCode status = super.getStatusCode(); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponse.java index f3af2a0ceb4..11194f21541 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,20 +60,6 @@ public interface ServerHttpResponse extends ReactiveHttpOutputMessage { return setStatusCode(value != null ? HttpStatusCode.valueOf(value) : null); } - /** - * Return the status code that has been set, or otherwise fall back on the - * status of the response from the underlying server. The return value may - * be {@code null} if there is no default value from the underlying server. - * @since 5.2.4 - * @deprecated in favor of {@link #getStatusCode()}, for removal in 7.0 - */ - @Deprecated(since = "6.0", forRemoval = true) - @Nullable - default Integer getRawStatusCode() { - HttpStatusCode httpStatus = getStatusCode(); - return (httpStatus != null ? httpStatus.value() : null); - } - /** * Return a mutable map with the cookies to send to the server. */ diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java index 4a15989648d..f9f7fda8283 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpResponseDecorator.java @@ -71,14 +71,6 @@ public class ServerHttpResponseDecorator implements ServerHttpResponse { return getDelegate().setRawStatusCode(value); } - @Override - @Nullable - @Deprecated - @SuppressWarnings("removal") - public Integer getRawStatusCode() { - return getDelegate().getRawStatusCode(); - } - @Override public HttpHeaders getHeaders() { return getDelegate().getHeaders(); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java index ccaf9b5733d..c2ccdbbcdda 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java @@ -104,14 +104,6 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse { return (status != null ? status : HttpStatusCode.valueOf(this.response.getStatus())); } - @Override - @Deprecated - @SuppressWarnings("removal") - public Integer getRawStatusCode() { - Integer status = super.getRawStatusCode(); - return (status != null ? status : this.response.getStatus()); - } - @Override protected void applyStatusCode() { HttpStatusCode status = super.getStatusCode(); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java index 9de01ff320e..65ed91a6042 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java @@ -87,14 +87,6 @@ class UndertowServerHttpResponse extends AbstractListenerServerHttpResponse impl return (status != null ? status : HttpStatusCode.valueOf(this.exchange.getStatusCode())); } - @Override - @Deprecated - @SuppressWarnings("removal") - public Integer getRawStatusCode() { - Integer status = super.getRawStatusCode(); - return (status != null ? status : this.exchange.getStatusCode()); - } - @Override protected void applyStatusCode() { HttpStatusCode status = super.getStatusCode(); diff --git a/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java b/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java index b1ce0f52587..93480e37127 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java +++ b/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,25 +66,6 @@ public class MissingServletRequestParameterException extends MissingRequestValue getBody().setDetail(initBodyDetail(this.parameterName)); } - /** - * Constructor for use when a value was present but converted to {@code null}. - * @param parameterName the name of the missing parameter - * @param parameterType the expected type of the missing parameter - * @param missingAfterConversion whether the value became null after conversion - * @since 5.3.6 - * @deprecated in favor of {@link #MissingServletRequestParameterException(String, MethodParameter, boolean)} - */ - @Deprecated(since = "6.1", forRemoval = true) - public MissingServletRequestParameterException( - String parameterName, String parameterType, boolean missingAfterConversion) { - - super("", missingAfterConversion, null, new Object[] {parameterName}); - this.parameterName = parameterName; - this.parameterType = parameterType; - this.parameter = null; - getBody().setDetail(initBodyDetail(this.parameterName)); - } - private static String initBodyDetail(String name) { return "Required parameter '" + name + "' is not present."; } diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 1388224300b..b9767b6b839 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -136,31 +136,9 @@ public class DefaultResponseErrorHandler implements ResponseErrorHandler { */ @Override public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException { - - // For backwards compatibility try handle(response) first - HandleErrorResponseDecorator decorator = new HandleErrorResponseDecorator(response); - handleError(decorator); - if (decorator.isHandled()) { - return; - } - handleError(response, response.getStatusCode(), url, method); } - @SuppressWarnings("removal") - @Override - public void handleError(ClientHttpResponse response) throws IOException { - - // Called via handleError(url, method, response) - if (response instanceof HandleErrorResponseDecorator decorator) { - decorator.setNotHandled(); - return; - } - - // Called directly, so do handle - handleError(response, response.getStatusCode(), null, null); - } - /** * Handle the error based on the resolved status code. *

The default implementation delegates to @@ -288,22 +266,4 @@ public class DefaultResponseErrorHandler implements ResponseErrorHandler { }; } - - private static class HandleErrorResponseDecorator extends ClientHttpResponseDecorator { - - private boolean handled = true; - - public HandleErrorResponseDecorator(ClientHttpResponse delegate) { - super(delegate); - } - - public void setNotHandled() { - this.handled = false; - } - - public boolean isHandled() { - return this.handled; - } - } - } diff --git a/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java index be96fb29a11..088b4138242 100644 --- a/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/ResponseErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,19 +52,6 @@ public interface ResponseErrorHandler { * @since 5.0 */ default void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException { - handleError(response); - } - - /** - * Handle the error in the given response. - *

This method is only called when {@link #hasError(ClientHttpResponse)} - * has returned {@code true}. - * @param response the response with the error - * @throws IOException in case of I/O errors - * @deprecated in favor of {@link #handleError(URI, HttpMethod, ClientHttpResponse)} - */ - @Deprecated(since = "6.2.1", forRemoval = true) - default void handleError(ClientHttpResponse response) throws IOException { } } diff --git a/spring-web/src/main/java/org/springframework/web/filter/reactive/ServerHttpObservationFilter.java b/spring-web/src/main/java/org/springframework/web/filter/reactive/ServerHttpObservationFilter.java deleted file mode 100644 index 8782c9d2639..00000000000 --- a/spring-web/src/main/java/org/springframework/web/filter/reactive/ServerHttpObservationFilter.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.filter.reactive; - -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; -import reactor.core.observability.DefaultSignalListener; -import reactor.core.publisher.Mono; -import reactor.util.context.Context; - -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention; -import org.springframework.http.server.reactive.observation.ServerHttpObservationDocumentation; -import org.springframework.http.server.reactive.observation.ServerRequestObservationContext; -import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebFilterChain; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; - -/** - * {@link org.springframework.web.server.WebFilter} that creates {@link Observation observations} - * for HTTP exchanges. This collects information about the execution time and - * information gathered from the {@link ServerRequestObservationContext}. - *

Web Frameworks can fetch the current {@link ServerRequestObservationContext context} - * as a {@link #CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE request attribute} and contribute - * additional information to it. - * The configured {@link ServerRequestObservationConvention} will use this context to collect - * {@link io.micrometer.common.KeyValue metadata} and attach it to the observation. - * - * @author Brian Clozel - * @since 6.0 - * @deprecated since 6.1 in favor of {@link WebHttpHandlerBuilder}. - */ -@Deprecated(since = "6.1", forRemoval = true) -public class ServerHttpObservationFilter implements WebFilter { - - /** - * Name of the request attribute holding the {@link ServerRequestObservationContext context} for the current observation. - */ - public static final String CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE = ServerHttpObservationFilter.class.getName() + ".context"; - - private static final ServerRequestObservationConvention DEFAULT_OBSERVATION_CONVENTION = new DefaultServerRequestObservationConvention(); - - private final ObservationRegistry observationRegistry; - - private final ServerRequestObservationConvention observationConvention; - - /** - * Create an {@code HttpRequestsObservationWebFilter} that records observations - * against the given {@link ObservationRegistry}. The default - * {@link DefaultServerRequestObservationConvention convention} will be used. - * @param observationRegistry the registry to use for recording observations - */ - public ServerHttpObservationFilter(ObservationRegistry observationRegistry) { - this(observationRegistry, DEFAULT_OBSERVATION_CONVENTION); - } - - /** - * Create an {@code HttpRequestsObservationWebFilter} that records observations - * against the given {@link ObservationRegistry} with a custom convention. - * @param observationRegistry the registry to use for recording observations - * @param observationConvention the convention to use for all recorded observations - */ - public ServerHttpObservationFilter(ObservationRegistry observationRegistry, ServerRequestObservationConvention observationConvention) { - this.observationRegistry = observationRegistry; - this.observationConvention = observationConvention; - } - - /** - * Get the current {@link ServerRequestObservationContext observation context} from the given request, if available. - * @param exchange the current exchange - * @return the current observation context - */ - public static Optional findObservationContext(ServerWebExchange exchange) { - return Optional.ofNullable(exchange.getAttribute(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE)); - } - - @Override - public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { - ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange.getRequest(), - exchange.getResponse(), exchange.getAttributes()); - exchange.getAttributes().put(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext); - return chain.filter(exchange).tap(() -> new ObservationSignalListener(observationContext)); - } - - private final class ObservationSignalListener extends DefaultSignalListener { - - private static final Set DISCONNECTED_CLIENT_EXCEPTIONS = Set.of("AbortedException", - "ClientAbortException", "EOFException", "EofException"); - - private final ServerRequestObservationContext observationContext; - - private final Observation observation; - - private final AtomicBoolean observationRecorded = new AtomicBoolean(); - - ObservationSignalListener(ServerRequestObservationContext observationContext) { - this.observationContext = observationContext; - this.observation = ServerHttpObservationDocumentation.HTTP_REACTIVE_SERVER_REQUESTS.observation(observationConvention, - DEFAULT_OBSERVATION_CONVENTION, () -> observationContext, observationRegistry); - } - - - @Override - public Context addToContext(Context originalContext) { - return originalContext.put(ObservationThreadLocalAccessor.KEY, this.observation); - } - - @Override - public void doFirst() throws Throwable { - this.observation.start(); - } - - @Override - public void doOnCancel() throws Throwable { - if (this.observationRecorded.compareAndSet(false, true)) { - this.observationContext.setConnectionAborted(true); - this.observation.stop(); - } - } - - @Override - public void doOnComplete() throws Throwable { - if (this.observationRecorded.compareAndSet(false, true)) { - doOnTerminate(this.observationContext); - } - } - - @Override - public void doOnError(Throwable error) throws Throwable { - if (this.observationRecorded.compareAndSet(false, true)) { - if (DISCONNECTED_CLIENT_EXCEPTIONS.contains(error.getClass().getSimpleName())) { - this.observationContext.setConnectionAborted(true); - } - this.observationContext.setError(error); - doOnTerminate(this.observationContext); - } - } - - private void doOnTerminate(ServerRequestObservationContext context) { - ServerHttpResponse response = context.getResponse(); - if (response != null) { - if (response.isCommitted()) { - this.observation.stop(); - } - else { - response.beforeCommit(() -> { - this.observation.stop(); - return Mono.empty(); - }); - } - } - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java b/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java index 54dce91f405..70b6c387794 100644 --- a/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java +++ b/spring-web/src/main/java/org/springframework/web/server/handler/ResponseStatusExceptionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,11 +88,10 @@ public class ResponseStatusExceptionHandler implements WebExceptionHandler { return "Resolved [" + className + ": " + message + "] for HTTP " + request.getMethod() + " " + path; } - @SuppressWarnings("deprecation") private boolean updateResponse(ServerHttpResponse response, Throwable ex) { boolean result = false; HttpStatusCode statusCode = determineStatus(ex); - int code = (statusCode != null ? statusCode.value() : determineRawStatusCode(ex)); + int code = (statusCode != null ? statusCode.value() : -1); if (code != -1) { if (response.setStatusCode(statusCode)) { if (ex instanceof ResponseStatusException responseStatusException) { @@ -127,19 +126,4 @@ public class ResponseStatusExceptionHandler implements WebExceptionHandler { } } - /** - * Determine the raw status code for the given exception. - * @param ex the exception to check - * @return the associated HTTP status code, or -1 if it can't be derived. - * @since 5.3 - * @deprecated in favor of {@link #determineStatus(Throwable)}, for removal in 7.0 - */ - @Deprecated(since = "6.0", forRemoval = true) - protected int determineRawStatusCode(Throwable ex) { - if (ex instanceof ResponseStatusException responseStatusException) { - return responseStatusException.getStatusCode().value(); - } - return -1; - } - } diff --git a/spring-web/src/main/java/org/springframework/web/service/invoker/AbstractReactorHttpExchangeAdapter.java b/spring-web/src/main/java/org/springframework/web/service/invoker/AbstractReactorHttpExchangeAdapter.java index 653a2b262f6..a11e6f51673 100644 --- a/spring-web/src/main/java/org/springframework/web/service/invoker/AbstractReactorHttpExchangeAdapter.java +++ b/spring-web/src/main/java/org/springframework/web/service/invoker/AbstractReactorHttpExchangeAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,6 @@ package org.springframework.web.service.invoker; import java.time.Duration; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.http.HttpHeaders; @@ -35,9 +32,7 @@ import org.springframework.util.Assert; * @author Rossen Stoyanchev * @since 6.1 */ -@SuppressWarnings("removal") -public abstract class AbstractReactorHttpExchangeAdapter - implements ReactorHttpExchangeAdapter, org.springframework.web.service.invoker.HttpClientAdapter { +public abstract class AbstractReactorHttpExchangeAdapter implements ReactorHttpExchangeAdapter { private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance(); @@ -126,46 +121,4 @@ public abstract class AbstractReactorHttpExchangeAdapter return entity; } - - // HttpClientAdapter implementation - - @Override - public Mono requestToVoid(HttpRequestValues requestValues) { - return exchangeForMono(requestValues); - } - - @Override - public Mono requestToHeaders(HttpRequestValues requestValues) { - return exchangeForHeadersMono(requestValues); - } - - @Override - public Mono requestToBody(HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - return exchangeForBodyMono(requestValues, bodyType); - } - - @Override - public Flux requestToBodyFlux(HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - return exchangeForBodyFlux(requestValues, bodyType); - } - - @Override - public Mono> requestToBodilessEntity(HttpRequestValues requestValues) { - return exchangeForBodilessEntityMono(requestValues); - } - - @Override - public Mono> requestToEntity( - HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - - return exchangeForEntityMono(requestValues, bodyType); - } - - @Override - public Mono>> requestToEntityFlux( - HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - - return exchangeForEntityFlux(requestValues, bodyType); - } - } diff --git a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpClientAdapter.java b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpClientAdapter.java deleted file mode 100644 index 75eaeb36fbb..00000000000 --- a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpClientAdapter.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2002-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.service.invoker; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; - -/** - * Contract to abstract the underlying HTTP client and decouple it from the - * {@linkplain HttpServiceProxyFactory#createClient(Class) HTTP service proxy}. - * - * @author Rossen Stoyanchev - * @author Olga Maciaszek-Sharma - * @since 6.0 - * @deprecated in favor of {@link ReactorHttpExchangeAdapter} - */ -@Deprecated(since = "6.1", forRemoval = true) -public interface HttpClientAdapter { - - /** - * Perform the given request, and release the response content, if any. - * @param requestValues the request to perform - * @return {@code Mono} that completes when the request is fully executed - * and the response content is released. - */ - Mono requestToVoid(HttpRequestValues requestValues); - - /** - * Perform the given request, release the response content, and return the - * response headers. - * @param requestValues the request to perform - * @return {@code Mono} that returns the response headers the request is - * fully executed and the response content released. - */ - Mono requestToHeaders(HttpRequestValues requestValues); - - /** - * Perform the given request and decode the response content to the given type. - * @param requestValues the request to perform - * @param bodyType the target type to decode to - * @return {@code Mono} that returns the decoded response. - * @param the type the response is decoded to - */ - Mono requestToBody(HttpRequestValues requestValues, ParameterizedTypeReference bodyType); - - /** - * Perform the given request and decode the response content to a stream with - * elements of the given type. - * @param requestValues the request to perform - * @param bodyType the target stream element type to decode to - * @return {@code Flux} with decoded stream elements. - * @param the type the response is decoded to - */ - Flux requestToBodyFlux(HttpRequestValues requestValues, ParameterizedTypeReference bodyType); - - /** - * Variant of {@link #requestToVoid(HttpRequestValues)} with additional - * access to the response status and headers. - */ - Mono> requestToBodilessEntity(HttpRequestValues requestValues); - - /** - * Variant of {@link #requestToBody(HttpRequestValues, ParameterizedTypeReference)} - * with additional access to the response status and headers. - */ - Mono> requestToEntity(HttpRequestValues requestValues, ParameterizedTypeReference bodyType); - - /** - * Variant of {@link #requestToBodyFlux(HttpRequestValues, ParameterizedTypeReference)} - * with additional access to the response status and headers. - */ - Mono>> requestToEntityFlux(HttpRequestValues requestValues, ParameterizedTypeReference bodyType); - - - /** - * Adapt this instance to {@link ReactorHttpExchangeAdapter}. - * @since 6.1 - */ - default ReactorHttpExchangeAdapter asReactorExchangeAdapter() { - - return new AbstractReactorHttpExchangeAdapter() { - - @Override - public boolean supportsRequestAttributes() { - return true; - } - - @Override - public Mono exchangeForMono(HttpRequestValues values) { - return HttpClientAdapter.this.requestToVoid(values); - } - - @Override - public Mono exchangeForHeadersMono(HttpRequestValues values) { - return HttpClientAdapter.this.requestToHeaders(values); - } - - @Override - public Mono exchangeForBodyMono(HttpRequestValues values, ParameterizedTypeReference bodyType) { - return HttpClientAdapter.this.requestToBody(values, bodyType); - } - - @Override - public Flux exchangeForBodyFlux(HttpRequestValues values, ParameterizedTypeReference bodyType) { - return HttpClientAdapter.this.requestToBodyFlux(values, bodyType); - } - - @Override - public Mono> exchangeForBodilessEntityMono(HttpRequestValues values) { - return HttpClientAdapter.this.requestToBodilessEntity(values); - } - - @Override - public Mono> exchangeForEntityMono( - HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - - return HttpClientAdapter.this.requestToEntity(requestValues, bodyType); - } - - @Override - public Mono>> exchangeForEntityFlux( - HttpRequestValues requestValues, ParameterizedTypeReference bodyType) { - - return HttpClientAdapter.this.requestToEntityFlux(requestValues, bodyType); - } - }; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java index 184ef4a51a1..fe4a465c08c 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java @@ -86,21 +86,6 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { this.contentCacheLimit = (cacheLimit > 0 ? cacheLimit : null); } - /** - * Create a new ContentCachingRequestWrapper for the given servlet request. - * @param request the original servlet request - * @deprecated in favor of {@link #ContentCachingRequestWrapper(HttpServletRequest, int)} - * in order to explicitly choose the cache limit - */ - @Deprecated(since = "6.2.1", forRemoval = true) - public ContentCachingRequestWrapper(HttpServletRequest request) { - super(request); - int contentLength = request.getContentLength(); - this.cachedContent = (contentLength > 0 ? - new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream()); - this.contentCacheLimit = null; - } - @Override public ServletInputStream getInputStream() throws IOException { diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index f436bc2e96e..422142082a1 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -30,7 +30,6 @@ import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.springframework.http.HttpRequest; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -243,34 +242,6 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { return fromUriString(httpUrl); } - /** - * Create a new {@code UriComponents} object from the URI associated with - * the given HttpRequest while also overlaying with values from the headers - * "Forwarded" (RFC 7239), - * or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if - * "Forwarded" is not found. - * @param request the source request - * @return the URI components of the URI - * @since 4.1.5 - * @deprecated in favor of {@link ForwardedHeaderUtils#adaptFromForwardedHeaders}; - * to be removed in 7.0 - */ - @Deprecated(since = "6.1", forRemoval = true) - public static UriComponentsBuilder fromHttpRequest(HttpRequest request) { - return ForwardedHeaderUtils.adaptFromForwardedHeaders(request.getURI(), request.getHeaders()); - } - - /** - * Create an instance by parsing the "Origin" header of an HTTP request. - * @see RFC 6454 - * @deprecated in favor of {@link UriComponentsBuilder#fromUriString(String)}; - * to be removed in 7.0 - */ - @Deprecated(since = "6.2", forRemoval = true) - public static UriComponentsBuilder fromOriginHeader(String origin) { - return fromUriString(origin); - } - // Encode methods diff --git a/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java b/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java index ff9a2055511..3ede45acee0 100644 --- a/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java +++ b/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java @@ -19,7 +19,6 @@ package org.springframework.http; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Random; @@ -279,221 +278,6 @@ class MediaTypeTests { assertThat(audioBasic.isLessSpecific(MediaType.TEXT_HTML)).isFalse(); } - @Test - void specificityComparator() { - MediaType audioBasic = new MediaType("audio", "basic"); - MediaType audioWave = new MediaType("audio", "wave"); - MediaType audio = new MediaType("audio"); - MediaType audio03 = new MediaType("audio", "*", 0.3); - MediaType audio07 = new MediaType("audio", "*", 0.7); - MediaType audioBasicLevel = new MediaType("audio", "basic", Collections.singletonMap("level", "1")); - MediaType textHtml = new MediaType("text", "html"); - MediaType allXml = new MediaType("application", "*+xml"); - MediaType all = MediaType.ALL; - - @SuppressWarnings("removal") - Comparator comp = MediaType.SPECIFICITY_COMPARATOR; - - // equal - assertThat(comp.compare(audioBasic, audioBasic)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audio, audio)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audio07, audio07)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audio03, audio03)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audioBasicLevel, audioBasicLevel)).as("Invalid comparison result").isEqualTo(0); - - // specific to unspecific - assertThat(comp.compare(audioBasic, audio)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audioBasic, all)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audio, all)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(MediaType.APPLICATION_XHTML_XML, allXml)).as("Invalid comparison result").isLessThan(0); - - // unspecific to specific - assertThat(comp.compare(audio, audioBasic)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(allXml, MediaType.APPLICATION_XHTML_XML)).as("Invalid comparison result") - .isGreaterThan(0); - assertThat(comp.compare(all, audioBasic)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(all, audio)).as("Invalid comparison result").isGreaterThan(0); - - // qualifiers - assertThat(comp.compare(audio, audio07)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audio07, audio)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(audio07, audio03)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audio03, audio07)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(audio03, all)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(all, audio03)).as("Invalid comparison result").isGreaterThan(0); - - // other parameters - assertThat(comp.compare(audioBasic, audioBasicLevel)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(audioBasicLevel, audioBasic)).as("Invalid comparison result").isLessThan(0); - - // different types - assertThat(comp.compare(audioBasic, textHtml)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(textHtml, audioBasic)).as("Invalid comparison result").isEqualTo(0); - - // different subtypes - assertThat(comp.compare(audioBasic, audioWave)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audioWave, audioBasic)).as("Invalid comparison result").isEqualTo(0); - } - - @Test - @SuppressWarnings("removal") - public void sortBySpecificityRelated() { - MediaType audioBasic = new MediaType("audio", "basic"); - MediaType audio = new MediaType("audio"); - MediaType audio03 = new MediaType("audio", "*", 0.3); - MediaType audio07 = new MediaType("audio", "*", 0.7); - MediaType audioBasicLevel = new MediaType("audio", "basic", Collections.singletonMap("level", "1")); - MediaType all = MediaType.ALL; - - List expected = new ArrayList<>(); - expected.add(audioBasicLevel); - expected.add(audioBasic); - expected.add(audio); - expected.add(audio07); - expected.add(audio03); - expected.add(all); - - List result = new ArrayList<>(expected); - Random rnd = new Random(); - // shuffle & sort 10 times - for (int i = 0; i < 10; i++) { - Collections.shuffle(result, rnd); - MediaType.sortBySpecificity(result); - - for (int j = 0; j < result.size(); j++) { - assertThat(result.get(j)).as("Invalid media type at " + j).isSameAs(expected.get(j)); - } - } - } - - @Test - @SuppressWarnings("removal") - public void sortBySpecificityUnrelated() { - MediaType audioBasic = new MediaType("audio", "basic"); - MediaType audioWave = new MediaType("audio", "wave"); - MediaType textHtml = new MediaType("text", "html"); - - List expected = new ArrayList<>(); - expected.add(textHtml); - expected.add(audioBasic); - expected.add(audioWave); - - List result = new ArrayList<>(expected); - MediaType.sortBySpecificity(result); - - for (int i = 0; i < result.size(); i++) { - assertThat(result.get(i)).as("Invalid media type at " + i).isSameAs(expected.get(i)); - } - - } - - @Test - void qualityComparator() { - MediaType audioBasic = new MediaType("audio", "basic"); - MediaType audioWave = new MediaType("audio", "wave"); - MediaType audio = new MediaType("audio"); - MediaType audio03 = new MediaType("audio", "*", 0.3); - MediaType audio07 = new MediaType("audio", "*", 0.7); - MediaType audioBasicLevel = new MediaType("audio", "basic", Collections.singletonMap("level", "1")); - MediaType textHtml = new MediaType("text", "html"); - MediaType allXml = new MediaType("application", "*+xml"); - MediaType all = MediaType.ALL; - - @SuppressWarnings("removal") - Comparator comp = MediaType.QUALITY_VALUE_COMPARATOR; - - // equal - assertThat(comp.compare(audioBasic, audioBasic)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audio, audio)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audio07, audio07)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audio03, audio03)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audioBasicLevel, audioBasicLevel)).as("Invalid comparison result").isEqualTo(0); - - // specific to unspecific - assertThat(comp.compare(audioBasic, audio)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audioBasic, all)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audio, all)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(MediaType.APPLICATION_XHTML_XML, allXml)).as("Invalid comparison result").isLessThan(0); - - // unspecific to specific - assertThat(comp.compare(audio, audioBasic)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(all, audioBasic)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(all, audio)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(allXml, MediaType.APPLICATION_XHTML_XML)).as("Invalid comparison result") - .isGreaterThan(0); - - // qualifiers - assertThat(comp.compare(audio, audio07)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audio07, audio)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(audio07, audio03)).as("Invalid comparison result").isLessThan(0); - assertThat(comp.compare(audio03, audio07)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(audio03, all)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(all, audio03)).as("Invalid comparison result").isLessThan(0); - - // other parameters - assertThat(comp.compare(audioBasic, audioBasicLevel)).as("Invalid comparison result").isGreaterThan(0); - assertThat(comp.compare(audioBasicLevel, audioBasic)).as("Invalid comparison result").isLessThan(0); - - // different types - assertThat(comp.compare(audioBasic, textHtml)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(textHtml, audioBasic)).as("Invalid comparison result").isEqualTo(0); - - // different subtypes - assertThat(comp.compare(audioBasic, audioWave)).as("Invalid comparison result").isEqualTo(0); - assertThat(comp.compare(audioWave, audioBasic)).as("Invalid comparison result").isEqualTo(0); - } - - @Test - @SuppressWarnings("removal") - public void sortByQualityRelated() { - MediaType audioBasic = new MediaType("audio", "basic"); - MediaType audio = new MediaType("audio"); - MediaType audio03 = new MediaType("audio", "*", 0.3); - MediaType audio07 = new MediaType("audio", "*", 0.7); - MediaType audioBasicLevel = new MediaType("audio", "basic", Collections.singletonMap("level", "1")); - MediaType all = MediaType.ALL; - - List expected = new ArrayList<>(); - expected.add(audioBasicLevel); - expected.add(audioBasic); - expected.add(audio); - expected.add(all); - expected.add(audio07); - expected.add(audio03); - - List result = new ArrayList<>(expected); - Random rnd = new Random(); - // shuffle & sort 10 times - for (int i = 0; i < 10; i++) { - Collections.shuffle(result, rnd); - MediaType.sortByQualityValue(result); - - for (int j = 0; j < result.size(); j++) { - assertThat(result.get(j)).as("Invalid media type at " + j).isSameAs(expected.get(j)); - } - } - } - - @Test - @SuppressWarnings("removal") - public void sortByQualityUnrelated() { - MediaType audioBasic = new MediaType("audio", "basic"); - MediaType audioWave = new MediaType("audio", "wave"); - MediaType textHtml = new MediaType("text", "html"); - - List expected = new ArrayList<>(); - expected.add(textHtml); - expected.add(audioBasic); - expected.add(audioWave); - - List result = new ArrayList<>(expected); - MediaType.sortBySpecificity(result); - - for (int i = 0; i < result.size(); i++) { - assertThat(result.get(i)).as("Invalid media type at " + i).isSameAs(expected.get(i)); - } - } - @Test void testWithConversionService() { ConversionService conversionService = new DefaultConversionService(); diff --git a/spring-web/src/test/java/org/springframework/http/client/BufferingClientHttpRequestFactoryWithOkHttpTests.java b/spring-web/src/test/java/org/springframework/http/client/BufferingClientHttpRequestFactoryWithOkHttpTests.java deleted file mode 100644 index 0d2436996ba..00000000000 --- a/spring-web/src/test/java/org/springframework/http/client/BufferingClientHttpRequestFactoryWithOkHttpTests.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -/** - * Tests for {@link BufferingClientHttpRequestWrapper} for clients - * not supporting non-null, empty request bodies for GET requests. - */ -class BufferingClientHttpRequestFactoryWithOkHttpTests extends AbstractHttpRequestFactoryTests { - - @Override - @SuppressWarnings("removal") - protected ClientHttpRequestFactory createRequestFactory() { - return new BufferingClientHttpRequestFactory(new OkHttp3ClientHttpRequestFactory()); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactoryTests.java deleted file mode 100644 index 8ebc5397fad..00000000000 --- a/spring-web/src/test/java/org/springframework/http/client/OkHttp3ClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.client; - -import org.junit.jupiter.api.Test; - -import org.springframework.http.HttpMethod; - -/** - * @author Roy Clarkson - */ -class OkHttp3ClientHttpRequestFactoryTests extends AbstractHttpRequestFactoryTests { - - @SuppressWarnings("removal") - @Override - protected ClientHttpRequestFactory createRequestFactory() { - return new OkHttp3ClientHttpRequestFactory(); - } - - @Override - @Test - void httpMethods() throws Exception { - super.httpMethods(); - assertHttpMethod("patch", HttpMethod.PATCH); - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java index 916116fa45d..074fa8f36a0 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestClientIntegrationTests.java @@ -76,12 +76,10 @@ class RestClientIntegrationTests { @interface ParameterizedRestClientTest { } - @SuppressWarnings("removal") static Stream clientHttpRequestFactories() { return Stream.of( argumentSet("JDK HttpURLConnection", new SimpleClientHttpRequestFactory()), argumentSet("HttpComponents", new HttpComponentsClientHttpRequestFactory()), - argumentSet("OkHttp", new org.springframework.http.client.OkHttp3ClientHttpRequestFactory()), argumentSet("Jetty", new JettyClientHttpRequestFactory()), argumentSet("JDK HttpClient", new JdkClientHttpRequestFactory()), argumentSet("Reactor Netty", new ReactorClientHttpRequestFactory()) diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java index a189a518d14..4a595825229 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java @@ -90,12 +90,10 @@ class RestTemplateIntegrationTests extends AbstractMockWebServerTests { @interface ParameterizedRestTemplateTest { } - @SuppressWarnings("removal") static Stream clientHttpRequestFactories() { return Stream.of( argumentSet("JDK HttpURLConnection", new SimpleClientHttpRequestFactory()), argumentSet("HttpComponents", new HttpComponentsClientHttpRequestFactory()), - argumentSet("OkHttp", new org.springframework.http.client.OkHttp3ClientHttpRequestFactory()), argumentSet("Jetty", new JettyClientHttpRequestFactory()), argumentSet("JDK HttpClient", new JdkClientHttpRequestFactory()), argumentSet("Reactor Netty", new ReactorClientHttpRequestFactory()) diff --git a/spring-web/src/test/java/org/springframework/web/filter/reactive/ServerHttpObservationFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/reactive/ServerHttpObservationFilterTests.java deleted file mode 100644 index 89e15eef5e9..00000000000 --- a/spring-web/src/test/java/org/springframework/web/filter/reactive/ServerHttpObservationFilterTests.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2002-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.filter.reactive; - - -import java.util.Optional; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; -import io.micrometer.observation.tck.TestObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistryAssert; -import org.assertj.core.api.ThrowingConsumer; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.http.server.reactive.observation.ServerRequestObservationContext; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebFilterChain; -import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest; -import org.springframework.web.testfixture.server.MockServerWebExchange; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ServerHttpObservationFilter}. - * - * @author Brian Clozel - */ -@SuppressWarnings("removal") -class ServerHttpObservationFilterTests { - - private final TestObservationRegistry observationRegistry = TestObservationRegistry.create(); - - private final ServerHttpObservationFilter filter = new ServerHttpObservationFilter(this.observationRegistry); - - @Test - void filterShouldFillObservationContext() { - ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource")); - exchange.getResponse().setRawStatusCode(200); - WebFilterChain filterChain = createFilterChain(filterExchange -> { - Optional observationContext = ServerHttpObservationFilter.findObservationContext(filterExchange); - assertThat(observationContext).isPresent(); - assertThat(observationContext.get().getCarrier()).isEqualTo(exchange.getRequest()); - assertThat(observationContext.get().getResponse()).isEqualTo(exchange.getResponse()); - }); - this.filter.filter(exchange, filterChain).block(); - assertThatHttpObservation().hasLowCardinalityKeyValue("outcome", "SUCCESS"); - } - - @Test - void filterShouldAddNewObservationToReactorContext() { - ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource")); - exchange.getResponse().setRawStatusCode(200); - WebFilterChain filterChain = webExchange -> Mono.deferContextual(contextView -> { - Observation observation = contextView.get(ObservationThreadLocalAccessor.KEY); - assertThat(observation).isNotNull(); - // check that the observation was started - assertThat(observation.getContext().getLowCardinalityKeyValue("outcome")).isNotNull(); - return Mono.empty(); - }); - this.filter.filter(exchange, filterChain).block(); - assertThatHttpObservation().hasLowCardinalityKeyValue("outcome", "SUCCESS"); - } - - @Test - void filterShouldUseThrownException() { - ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource")); - exchange.getResponse().setRawStatusCode(500); - WebFilterChain filterChain = createFilterChain(filterExchange -> { - throw new IllegalArgumentException("server error"); - }); - StepVerifier.create(this.filter.filter(exchange, filterChain)) - .expectError(IllegalArgumentException.class) - .verify(); - Optional observationContext = ServerHttpObservationFilter.findObservationContext(exchange); - assertThat(observationContext.get().getError()).isInstanceOf(IllegalArgumentException.class); - assertThatHttpObservation().hasLowCardinalityKeyValue("outcome", "SERVER_ERROR"); - } - - @Test - void filterShouldRecordObservationWhenCancelled() { - ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource")); - exchange.getResponse().setRawStatusCode(200); - WebFilterChain filterChain = createFilterChain(filterExchange -> { - }); - StepVerifier.create(this.filter.filter(exchange, filterChain)) - .thenCancel() - .verify(); - assertThatHttpObservation().hasLowCardinalityKeyValue("outcome", "UNKNOWN"); - } - - @Test - void filterShouldStopObservationOnResponseCommit() { - ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource")); - WebFilterChain filterChain = createFilterChain(filterExchange -> { - throw new IllegalArgumentException("server error"); - }); - StepVerifier.create(this.filter.filter(exchange, filterChain).doOnError(throwable -> { - ServerHttpResponse response = exchange.getResponse(); - response.setRawStatusCode(500); - response.setComplete().block(); - })) - .expectError(IllegalArgumentException.class) - .verify(); - Optional observationContext = ServerHttpObservationFilter.findObservationContext(exchange); - assertThat(observationContext.get().getError()).isInstanceOf(IllegalArgumentException.class); - assertThatHttpObservation().hasLowCardinalityKeyValue("outcome", "SERVER_ERROR"); - } - - - private WebFilterChain createFilterChain(ThrowingConsumer exchangeConsumer) { - return filterExchange -> { - try { - exchangeConsumer.accept(filterExchange); - } - catch (Throwable ex) { - return Mono.error(ex); - } - return Mono.empty(); - }; - } - - private TestObservationRegistryAssert.TestObservationRegistryAssertReturningObservationContextAssert assertThatHttpObservation() { - return assertThat(this.observationRegistry).hasObservationWithNameEqualTo("http.server.requests").that(); - } -} diff --git a/spring-webflux/spring-webflux.gradle b/spring-webflux/spring-webflux.gradle index e05cd2b9461..1ea20efabc8 100644 --- a/spring-webflux/spring-webflux.gradle +++ b/spring-webflux/spring-webflux.gradle @@ -33,7 +33,6 @@ dependencies { optional("org.jetbrains.kotlin:kotlin-reflect") optional("org.jetbrains.kotlin:kotlin-stdlib") optional("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") - optional("org.webjars:webjars-locator-core") optional("org.webjars:webjars-locator-lite") testImplementation(testFixtures(project(":spring-beans"))) testImplementation(testFixtures(project(":spring-core"))) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceChainRegistration.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceChainRegistration.java index 376daf987aa..fe7318feb02 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceChainRegistration.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceChainRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import org.springframework.web.reactive.resource.PathResourceResolver; import org.springframework.web.reactive.resource.ResourceResolver; import org.springframework.web.reactive.resource.ResourceTransformer; import org.springframework.web.reactive.resource.VersionResourceResolver; -import org.springframework.web.reactive.resource.WebJarsResourceResolver; /** * Assists with the registration of resource resolvers and transformers. @@ -44,10 +43,7 @@ public class ResourceChainRegistration { private static final String DEFAULT_CACHE_NAME = "spring-resource-chain-cache"; - private static final boolean isWebJarAssetLocatorPresent = ClassUtils.isPresent( - "org.webjars.WebJarAssetLocator", ResourceChainRegistration.class.getClassLoader()); - - private static final boolean isWebJarVersionLocatorPresent = ClassUtils.isPresent( + private static final boolean webJarsPresent = ClassUtils.isPresent( "org.webjars.WebJarVersionLocator", ResourceChainRegistration.class.getClassLoader()); @@ -93,7 +89,7 @@ public class ResourceChainRegistration { else if (resolver instanceof PathResourceResolver) { this.hasPathResolver = true; } - else if (resolver instanceof WebJarsResourceResolver || resolver instanceof LiteWebJarsResourceResolver) { + else if (resolver instanceof LiteWebJarsResourceResolver) { this.hasWebjarsResolver = true; } return this; @@ -113,16 +109,12 @@ public class ResourceChainRegistration { return this; } - @SuppressWarnings("removal") protected List getResourceResolvers() { if (!this.hasPathResolver) { List result = new ArrayList<>(this.resolvers); - if (isWebJarVersionLocatorPresent && !this.hasWebjarsResolver) { + if (webJarsPresent && !this.hasWebjarsResolver) { result.add(new LiteWebJarsResourceResolver()); } - else if (isWebJarAssetLocatorPresent && !this.hasWebjarsResolver) { - result.add(new WebJarsResourceResolver()); - } result.add(new PathResourceResolver()); return result; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequestObservationContext.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequestObservationContext.java index deba7061c09..434ca9f140b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequestObservationContext.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ClientRequestObservationContext.java @@ -42,15 +42,6 @@ public class ClientRequestObservationContext extends RequestReplySenderContext attributes, ServerRequest serverRequest, HandlerFunction handlerFunction) { @@ -171,9 +171,6 @@ public class RouterFunctionMapping extends AbstractHandlerMapping implements Ini PathPattern matchingPattern = (PathPattern) attributes.get(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE); if (matchingPattern != null) { attributes.put(BEST_MATCHING_PATTERN_ATTRIBUTE, matchingPattern); - org.springframework.web.filter.reactive.ServerHttpObservationFilter - .findObservationContext(serverRequest.exchange()) - .ifPresent(context -> context.setPathPattern(matchingPattern.toString())); ServerRequestObservationContext.findCurrent(serverRequest.exchange().getAttributes()) .ifPresent(context -> context.setPathPattern(matchingPattern.toString())); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java index 610ad285317..01263e6050e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -167,9 +167,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { exchange.getAttributes().put(BEST_MATCHING_HANDLER_ATTRIBUTE, handler); exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, pattern); - org.springframework.web.filter.reactive.ServerHttpObservationFilter - .findObservationContext(exchange) - .ifPresent(context -> context.setPathPattern(pattern.toString())); ServerRequestObservationContext.findCurrent(exchange.getAttributes()) .ifPresent(context -> context.setPathPattern(pattern.toString())); exchange.getAttributes().put(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/WebJarsResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/WebJarsResourceResolver.java deleted file mode 100644 index c851a379f7e..00000000000 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/WebJarsResourceResolver.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2002-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.reactive.resource; - -import java.util.List; - -import org.webjars.WebJarAssetLocator; -import reactor.core.publisher.Mono; - -import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; -import org.springframework.web.server.ServerWebExchange; - -/** - * A {@code ResourceResolver} that delegates to the chain to locate a resource and then - * attempts to find a matching versioned resource contained in a WebJar JAR file. - * - *

This allows WebJars.org users to write version agnostic paths in their templates, - * like {@code