From df376d934315e211981c1aca7743559913eb2708 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Nov 2024 15:08:40 +0100 Subject: [PATCH 1/4] Upgrade to Micrometer 1.12.12 and Reactor 2023.0.12 Includes Netty 4.1.114, Jetty 12.0.15, Jetty Reactive HttpClient 4.0.8, RxJava 3.1.9, RSocket 1.1.4, Groovy 4.0.24, JRuby 9.4.9, Checkstyle 10.20.1 Closes gh-33877 Closes gh-33879 --- .../build/CheckstyleConventions.java | 2 +- framework-platform/framework-platform.gradle | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java b/buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java index db28118a74..bd4bcba568 100644 --- a/buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java +++ b/buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java @@ -50,7 +50,7 @@ public class CheckstyleConventions { project.getPlugins().apply(CheckstylePlugin.class); project.getTasks().withType(Checkstyle.class).forEach(checkstyle -> checkstyle.getMaxHeapSize().set("1g")); CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class); - checkstyle.setToolVersion("10.18.1"); + checkstyle.setToolVersion("10.20.1"); checkstyle.getConfigDirectory().set(project.getRootProject().file("src/checkstyle")); String version = SpringJavaFormatPlugin.class.getPackage().getImplementationVersion(); DependencySet checkstyleDependencies = project.getConfigurations().getByName("checkstyle").getDependencies(); diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index 566e45fd78..c1b3a33739 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -8,16 +8,16 @@ javaPlatform { dependencies { api(platform("com.fasterxml.jackson:jackson-bom:2.15.4")) - api(platform("io.micrometer:micrometer-bom:1.12.11")) - api(platform("io.netty:netty-bom:4.1.113.Final")) + api(platform("io.micrometer:micrometer-bom:1.12.12")) + api(platform("io.netty:netty-bom:4.1.114.Final")) api(platform("io.netty:netty5-bom:5.0.0.Alpha5")) - api(platform("io.projectreactor:reactor-bom:2023.0.11")) - api(platform("io.rsocket:rsocket-bom:1.1.3")) - api(platform("org.apache.groovy:groovy-bom:4.0.23")) + api(platform("io.projectreactor:reactor-bom:2023.0.12")) + api(platform("io.rsocket:rsocket-bom:1.1.4")) + api(platform("org.apache.groovy:groovy-bom:4.0.24")) api(platform("org.apache.logging.log4j:log4j-bom:2.21.1")) api(platform("org.assertj:assertj-bom:3.26.3")) - api(platform("org.eclipse.jetty:jetty-bom:12.0.13")) - api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.13")) + api(platform("org.eclipse.jetty:jetty-bom:12.0.15")) + api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.15")) api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3")) api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3")) api(platform("org.junit:junit-bom:5.10.5")) @@ -54,7 +54,7 @@ dependencies { api("io.r2dbc:r2dbc-h2:1.0.0.RELEASE") api("io.r2dbc:r2dbc-spi-test:1.0.0.RELEASE") api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE") - api("io.reactivex.rxjava3:rxjava:3.1.8") + api("io.reactivex.rxjava3:rxjava:3.1.9") api("io.smallrye.reactive:mutiny:1.10.0") api("io.undertow:undertow-core:2.3.17.Final") api("io.undertow:undertow-servlet:2.3.17.Final") @@ -116,7 +116,7 @@ dependencies { api("org.codehaus.jettison:jettison:1.5.4") api("org.crac:crac:1.4.0") api("org.dom4j:dom4j:2.1.4") - api("org.eclipse.jetty:jetty-reactive-httpclient:4.0.7") + api("org.eclipse.jetty:jetty-reactive-httpclient:4.0.8") api("org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.4") api("org.eclipse:yasson:2.0.4") api("org.ehcache:ehcache:3.10.8") @@ -131,7 +131,7 @@ dependencies { api("org.hibernate:hibernate-validator:7.0.5.Final") api("org.hsqldb:hsqldb:2.7.2") api("org.javamoney:moneta:1.4.4") - api("org.jruby:jruby:9.4.8.0") + api("org.jruby:jruby:9.4.9.0") api("org.junit.support:testng-engine:1.0.5") api("org.mozilla:rhino:1.7.15") api("org.ogce:xpp3:1.1.6") From 01c85b1afbe18571e0144fad0c1a8fd3a4369079 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Nov 2024 15:09:02 +0100 Subject: [PATCH 2/4] Add explicit note on blocking in case of concurrency limit Closes gh-33873 --- .../springframework/core/task/SimpleAsyncTaskExecutor.java | 5 +++++ 1 file changed, 5 insertions(+) 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 8412e6c4af..def172a7ed 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 @@ -196,6 +196,11 @@ public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator * The default of -1 indicates no concurrency limit at all. *

This is the equivalent of a maximum pool size in a thread pool, * preventing temporary overload of the thread management system. + * However, in contrast to a thread pool with a managed task queue, + * this executor will block the submitter until the task can be + * accepted when the configured concurrency limit has been reached. + * If you prefer queue-based task hand-offs without such blocking, + * consider using a {@code ThreadPoolTaskExecutor} instead. * @see #UNBOUNDED_CONCURRENCY * @see org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor#setMaxPoolSize */ From 62eb21f93867d4fef7570b8e1db8352845905827 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Nov 2024 15:09:58 +0100 Subject: [PATCH 3/4] Add note on declaring autowired fields as ObjectProvider Closes gh-33834 --- .../springframework/cache/annotation/CachingConfigurer.java | 4 ++++ .../annotation/TransactionManagementConfigurer.java | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java index 85c372dfeb..05babe1da4 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CachingConfigurer.java @@ -32,6 +32,10 @@ import org.springframework.lang.Nullable; * {@link #cacheManager()}, {@link #cacheResolver()}, {@link #keyGenerator()}, and * {@link #errorHandler()} for detailed instructions. * + *

NOTE: A {@code CachingConfigurer} will get initialized early. + * Do not inject common dependencies into autowired fields directly; instead, consider + * declaring a lazy {@link org.springframework.beans.factory.ObjectProvider} for those. + * * @author Chris Beams * @author Stephane Nicoll * @since 3.1 diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java index c6c4e37ff4..55775347ac 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionManagementConfigurer.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. @@ -30,6 +30,10 @@ import org.springframework.transaction.TransactionManager; *

See @{@link EnableTransactionManagement} for general examples and context; * see {@link #annotationDrivenTransactionManager()} for detailed instructions. * + *

NOTE: A {@code TransactionManagementConfigurer} will get initialized early. + * Do not inject common dependencies into autowired fields directly; instead, consider + * declaring a lazy {@link org.springframework.beans.factory.ObjectProvider} for those. + * *

Note that in by-type lookup disambiguation cases, an alternative approach to * implementing this interface is to simply mark one of the offending * {@code PlatformTransactionManager} {@code @Bean} methods (or From 14b9865de73f2aebefbc4c63b61c5732ad3bfbfd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Nov 2024 15:10:32 +0100 Subject: [PATCH 4/4] Remove ineffective JettyByteBufferIterator from WebSocket adapter In JettyWebSocketHandlerAdapter, JettyByteBufferIterator does not actually add extra behavior (in contrast to JettyClientHttpConnector). --- .../reactive/JettyClientHttpConnector.java | 5 +-- .../adapter/JettyWebSocketHandlerAdapter.java | 34 ++----------------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpConnector.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpConnector.java index a2895f6ded..d985ffbe17 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpConnector.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyClientHttpConnector.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. @@ -153,7 +153,6 @@ public class JettyClientHttpConnector implements ClientHttpConnector { private final AtomicInteger refCount = new AtomicInteger(1); - public JettyDataBuffer(DataBuffer delegate, Content.Chunk chunk) { Assert.notNull(delegate, "Delegate must not be null"); Assert.notNull(chunk, "Chunk must not be null"); @@ -390,7 +389,6 @@ public class JettyClientHttpConnector implements ClientHttpConnector { private final Content.Chunk chunk; - public JettyByteBufferIterator(ByteBufferIterator delegate, Content.Chunk chunk) { Assert.notNull(delegate, "Delegate must not be null"); Assert.notNull(chunk, "Chunk must not be null"); @@ -400,7 +398,6 @@ public class JettyClientHttpConnector implements ClientHttpConnector { this.chunk.retain(); } - @Override public void close() { this.delegate.close(); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java index 5e4b08d455..33db843968 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/JettyWebSocketHandlerAdapter.java @@ -306,48 +306,18 @@ public class JettyWebSocketHandlerAdapter { @Override public ByteBufferIterator readableByteBuffers() { - ByteBufferIterator delegateIterator = this.delegate.readableByteBuffers(); - return new JettyByteBufferIterator(delegateIterator); + return this.delegate.readableByteBuffers(); } @Override public ByteBufferIterator writableByteBuffers() { - ByteBufferIterator delegateIterator = this.delegate.writableByteBuffers(); - return new JettyByteBufferIterator(delegateIterator); + return this.delegate.writableByteBuffers(); } @Override public String toString(int index, int length, Charset charset) { return this.delegate.toString(index, length, charset); } - - - private static class JettyByteBufferIterator implements ByteBufferIterator { - - private final ByteBufferIterator delegate; - - - JettyByteBufferIterator(ByteBufferIterator delegate) { - Assert.notNull(delegate, "Delegate must not be null"); - - this.delegate = delegate; - } - - @Override - public void close() { - this.delegate.close(); - } - - @Override - public boolean hasNext() { - return this.delegate.hasNext(); - } - - @Override - public ByteBuffer next() { - return this.delegate.next(); - } - } } }