From 301a6baf342bcd767c2a2ccac714e6437fc1384c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:15 +0000 Subject: [PATCH 01/23] Start building against Micrometer 1.16.3 snapshots See gh-49085 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 4fbaf13ba04..2de9aa6dcdf 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1535,7 +1535,7 @@ bom { releaseNotes("https://github.com/apache/maven-war-plugin/releases/tag/maven-war-plugin-{version}") } } - library("Micrometer", "1.16.2") { + library("Micrometer", "1.16.3-SNAPSHOT") { considerSnapshots() group("io.micrometer") { modules = [ From 5a0f04b46aa9d535a8fe655452f6a476c6e74b2b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:19 +0000 Subject: [PATCH 02/23] Start building against Micrometer Tracing 1.6.3 snapshots See gh-49086 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 2de9aa6dcdf..3114308cebd 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1558,7 +1558,7 @@ bom { releaseNotes("https://github.com/micrometer-metrics/micrometer/releases/tag/v{version}") } } - library("Micrometer Tracing", "1.6.2") { + library("Micrometer Tracing", "1.6.3-SNAPSHOT") { considerSnapshots() group("io.micrometer") { bom("micrometer-tracing-bom") From a466e2d6182f477f507917a50d03afcb4fdc9d6b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:24 +0000 Subject: [PATCH 03/23] Start building against Reactor Bom 2025.0.3 snapshots See gh-49087 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 3114308cebd..83078b7a5f8 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1953,7 +1953,7 @@ bom { ] } } - library("Reactor Bom", "2025.0.2") { + library("Reactor Bom", "2025.0.3-SNAPSHOT") { considerSnapshots() calendarName = "Reactor" group("io.projectreactor") { From 178094621482990466ed5f3870b55351e3613108 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:28 +0000 Subject: [PATCH 04/23] Start building against Spring Data Bom 2025.1.3 snapshots See gh-49088 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 83078b7a5f8..8887cc14f33 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2401,7 +2401,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-batch/releases/tag/v{version}") } } - library("Spring Data Bom", "2025.1.2") { + library("Spring Data Bom", "2025.1.3-SNAPSHOT") { considerSnapshots() calendarName = "Spring Data Release" group("org.springframework.data") { From 08607c60df49ad1a97794ac82482df2bf72a75fb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:32 +0000 Subject: [PATCH 05/23] Start building against Spring Framework 7.0.4 snapshots See gh-49089 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index df9e228d899..be2c2fefb96 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,7 +21,7 @@ mockitoVersion=5.20.0 nativeBuildToolsVersion=0.11.4 nullabilityPluginVersion=0.0.11 snakeYamlVersion=2.5 -springFrameworkVersion=7.0.3 +springFrameworkVersion=7.0.4-SNAPSHOT springFramework60xVersion=6.0.23 tomcatVersion=11.0.15 From e85b3e403a70a5208c7a221b65f0f9171273cad6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:37 +0000 Subject: [PATCH 06/23] Start building against Spring Kafka 4.0.3 snapshots See gh-49090 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 8887cc14f33..4f3d0e41c6e 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2481,7 +2481,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-integration/releases/tag/v{version}") } } - library("Spring Kafka", "4.0.2") { + library("Spring Kafka", "4.0.3-SNAPSHOT") { considerSnapshots() group("org.springframework.kafka") { modules = [ From 0f2ac3ae80df8102d6201711cf850138b6afc445 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:42 +0000 Subject: [PATCH 07/23] Start building against Spring LDAP 4.0.2 snapshots See gh-49091 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 4f3d0e41c6e..178db1f87af 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2499,7 +2499,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-kafka/releases/tag/v{version}") } } - library("Spring LDAP", "4.0.1") { + library("Spring LDAP", "4.0.2-SNAPSHOT") { considerSnapshots() group("org.springframework.ldap") { modules = [ From ff654efd5827e750d39c2f9bcd2d9c25bcc47025 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:46 +0000 Subject: [PATCH 08/23] Start building against Spring Pulsar 2.0.3 snapshots See gh-49092 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 178db1f87af..3711433ab43 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2519,7 +2519,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-ldap/releases/tag/{version}") } } - library("Spring Pulsar", "2.0.2") { + library("Spring Pulsar", "2.0.3-SNAPSHOT") { considerSnapshots() group("org.springframework.pulsar") { bom("spring-pulsar-bom") From 87a41f14cb97016cf24cbdc7095527decb83c261 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:38:50 +0000 Subject: [PATCH 09/23] Start building against Spring Security 7.0.3 snapshots See gh-49093 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 3711433ab43..a8ff49aeb1e 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2549,7 +2549,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-restdocs/releases/tag/v{version}") } } - library("Spring Security", "7.0.2") { + library("Spring Security", "7.0.3-SNAPSHOT") { considerSnapshots() group("org.springframework.security") { bom("spring-security-bom") From 7d8d9c044b65f310da8e6989e09ce71a7631fb23 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:41:54 +0000 Subject: [PATCH 10/23] Upgrade to AssertJ 3.27.7 Closes gh-49095 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index be2c2fefb96..900e9cb2338 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.caching=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx3g -Dfile.encoding=UTF-8 -assertjVersion=3.27.6 +assertjVersion=3.27.7 checkstyleToolVersion=10.12.4 commonsCodecVersion=1.19.0 graalVersion=25 From 0419be2ebff2e76226e1821ef0a41a07152d0659 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:41:58 +0000 Subject: [PATCH 11/23] Upgrade to Elasticsearch Client 9.2.4 Closes gh-49096 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index a8ff49aeb1e..4139422e9ca 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -355,7 +355,7 @@ bom { releaseNotes("https://github.com/ehcache/ehcache3/releases/tag/v{version}") } } - library("Elasticsearch Client", "9.2.3") { + library("Elasticsearch Client", "9.2.4") { prohibit { contains "-alpha" contains "-beta" From 8adac642334aafd375177392ba54f7753e63d1cb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:03 +0000 Subject: [PATCH 12/23] Upgrade to Groovy 5.0.4 Closes gh-49097 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 4139422e9ca..efc66254079 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -498,7 +498,7 @@ bom { releaseNotes("https://github.com/graphql-java/graphql-java/releases/tag/v{version}") } } - library("Groovy", "5.0.3") { + library("Groovy", "5.0.4") { prohibit { contains "-alpha-" because "we don't want alpha dependencies" From 9f3018f0ac00c395a918b02b28c39efe74c75032 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:07 +0000 Subject: [PATCH 13/23] Upgrade to Hibernate 7.2.3.Final Closes gh-49098 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index efc66254079..b96139a9be9 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -563,7 +563,7 @@ bom { releaseNotes("https://github.com/hazelcast/hazelcast/releases/tag/v{version}") } } - library("Hibernate", "7.2.1.Final") { + library("Hibernate", "7.2.3.Final") { group("org.hibernate.orm") { modules = [ "hibernate-agroal", From a67203bcc901d0ae39ccd31e0ae7e826c634a14f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:11 +0000 Subject: [PATCH 14/23] Upgrade to Jaybird 6.0.4 Closes gh-49099 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index b96139a9be9..f2b82c5390f 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -967,7 +967,7 @@ bom { releaseNotes("https://github.com/jaxen-xpath/jaxen/releases/tag/v{version}") } } - library("Jaybird", "6.0.3") { + library("Jaybird", "6.0.4") { prohibit { endsWith ".java8" because "we use the .java11 version" From 95858994b7bb29b329a529debb3d89ef9da92024 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:16 +0000 Subject: [PATCH 15/23] Upgrade to JBoss Logging 3.6.2.Final Closes gh-49100 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index f2b82c5390f..19728ec23da 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -982,7 +982,7 @@ bom { .formatted(version.toString().replace(".java11", ""))) } } - library("JBoss Logging", "3.6.1.Final") { + library("JBoss Logging", "3.6.2.Final") { group("org.jboss.logging") { modules = [ "jboss-logging" From b01b8145b5bad4fb284d58312237140e5237df54 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:20 +0000 Subject: [PATCH 16/23] Upgrade to Jersey 4.0.2 Closes gh-49101 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 19728ec23da..05c92fac3bd 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1020,7 +1020,7 @@ bom { releaseNotes("https://github.com/redis/jedis/releases/tag/v{version}") } } - library("Jersey", "4.0.0") { + library("Jersey", "4.0.2") { group("org.glassfish.jersey") { bom("jersey-bom") } From 4bbb0f731cacb760481221087c00b353661357fb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:24 +0000 Subject: [PATCH 17/23] Upgrade to Jetty 12.1.6 Closes gh-49102 --- ...rtualThreadsWebServerFactoryCustomizer.java | 18 +++++++++++------- ...ThreadsWebServerFactoryCustomizerTests.java | 2 +- platform/spring-boot-dependencies/build.gradle | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java index 2bf589296a5..820f1d96dc0 100644 --- a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java +++ b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java @@ -21,7 +21,6 @@ import org.eclipse.jetty.util.thread.VirtualThreadPool; import org.jspecify.annotations.Nullable; import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; -import org.springframework.boot.jetty.autoconfigure.JettyServerProperties.Threads; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.core.Ordered; import org.springframework.util.Assert; @@ -62,16 +61,21 @@ public class JettyVirtualThreadsWebServerFactoryCustomizer @Override public void customize(ConfigurableJettyWebServerFactory factory) { Assert.state(VirtualThreads.areSupported(), "Virtual threads are not supported"); - VirtualThreadPool virtualThreadPool = new VirtualThreadPool(); + Integer maxTasks = getMaxTasks(); + VirtualThreadPool virtualThreadPool = (maxTasks != null) ? new VirtualThreadPool(maxTasks) + : new VirtualThreadPool(); virtualThreadPool.setName("jetty-"); - if (this.serverProperties != null) { - Threads properties = this.serverProperties.getThreads(); - int maxThreadCount = (properties.getMax() > 0) ? properties.getMax() : 200; - virtualThreadPool.setMaxThreads(maxThreadCount); - } factory.setThreadPool(virtualThreadPool); } + private @Nullable Integer getMaxTasks() { + if (this.serverProperties == null) { + return null; + } + Integer maxThreads = this.serverProperties.getThreads().getMax(); + return (maxThreads > 0) ? maxThreads : null; + } + @Override public int getOrder() { return JettyWebServerFactoryCustomizer.ORDER + 1; diff --git a/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java b/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java index c5d31db9b4e..06e01be448b 100644 --- a/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java +++ b/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java @@ -48,7 +48,7 @@ class JettyVirtualThreadsWebServerFactoryCustomizerTests { assertThat(threadPool).isInstanceOf(VirtualThreadPool.class); VirtualThreadPool virtualThreadPool = (VirtualThreadPool) threadPool; assertThat(virtualThreadPool.getName()).isEqualTo("jetty-"); - assertThat(virtualThreadPool.getMaxThreads()).isEqualTo(100); + assertThat(virtualThreadPool.getMaxConcurrentTasks()).isEqualTo(100); })); } diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 05c92fac3bd..f31b319c65f 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1037,7 +1037,7 @@ bom { ] } } - library("Jetty", "12.1.5") { + library("Jetty", "12.1.6") { prohibit { contains ".alpha" because "we don't want alpha dependencies" From 23f2eec5fca79b6962ebc48beac61bd2a01e8e6c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:29 +0000 Subject: [PATCH 18/23] Upgrade to jOOQ 3.19.30 Closes gh-49103 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index f31b319c65f..2b1d6e21fcb 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1061,7 +1061,7 @@ bom { ] } } - library("jOOQ", "3.19.29") { + library("jOOQ", "3.19.30") { prohibit { versionRange "[3.20.0,)" because "it requires Java 21" From bfa1c0657110bb486a42f30be3d29ba90ca0a6fa Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:33 +0000 Subject: [PATCH 19/23] Upgrade to Logback 1.5.27 Closes gh-49104 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 2b1d6e21fcb..2f9686fa006 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1295,7 +1295,7 @@ bom { releaseNotes("https://github.com/apache/logging-log4j2/releases/tag/rel%2F{version}") } } - library("Logback", "1.5.25") { + library("Logback", "1.5.27") { group("ch.qos.logback") { modules = [ "logback-classic", From 3922ee81441f3f83273b188ca3b2dfb00e684ab5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:37 +0000 Subject: [PATCH 20/23] Upgrade to MongoDB 5.6.3 Closes gh-49105 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 2f9686fa006..343edbb10c1 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1580,7 +1580,7 @@ bom { releaseNotes("https://github.com/mockito/mockito/releases/tag/v{version}") } } - library("MongoDB", "5.6.2") { + library("MongoDB", "5.6.3") { alignWith { version { of "org.mongodb:mongodb-driver-core" From b5aac0dff0a076717c075b93a369704a7e40cba6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:42 +0000 Subject: [PATCH 21/23] Upgrade to MySQL 9.6.0 Closes gh-49106 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 343edbb10c1..d91e397164b 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1619,7 +1619,7 @@ bom { .formatted(version.toString().replace(".jre11", ""))) } } - library("MySQL", "9.5.0") { + library("MySQL", "9.6.0") { upgradePolicy = "same-major-version" group("com.mysql") { modules = [ From 10c55a9debebddffd683e800b60eeffbd7a5dd72 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:46 +0000 Subject: [PATCH 22/23] Upgrade to Netty 4.2.10.Final Closes gh-49107 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index d91e397164b..0e0326f4f49 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1674,7 +1674,7 @@ bom { releaseNotes("https://github.com/neo4j/neo4j-java-driver/releases/tag/{version}") } } - library("Netty", "4.2.9.Final") { + library("Netty", "4.2.10.Final") { prohibit { contains ".Alpha" contains ".Beta" From dfd4b8528999e7c59217bd399b30afbc3a743496 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 5 Feb 2026 12:42:50 +0000 Subject: [PATCH 23/23] Upgrade to Tomcat 11.0.18 Tomcat 9.0.115, 10.1.52, and 11.0.18 include a breaking change [1] to how ciphers are configured when using HTTPS. Previously, a single setting was used but this has now been split in two; the existing ciphers setting for TLSv1.2 ciphers and a new ciperSuites setting for TLSv1.3. As part of this split, the behavior of the ciphers setting has been changed such that any TLSv1.3 ciphers are ignored and a warning is logged. This change in Tomcat is problematic without also making some changes in Boot. If we had done nothing, a user that had configured only TLSv1.3 cipers would have them all ignored, leaving their SSL connection unexpectedly using all of the default ciphers which may be less secure. This commit adapts to the breaking change in Tomcat by taking the user's list of ciphers and splitting into into TLSv1.2 and TLSv1.3 ciphers before passing them into Tomcat's two settings (ciphers and cipherSuites respectively). This is done defensively for backwards compatibility. If the methods to identify and configure the TLSv1.3 ciphers are not present, we assume that we're running with an earlier version of Tomcat and fall back to passing them all into the ciphers setting as we did previously. Closes gh-49108 [1] https://github.com/apache/tomcat/commit/9abf6bddb2e84ecf1668780bb3150b799f832ccf --- gradle.properties | 2 +- .../boot/tomcat/SslConnectorCustomizer.java | 64 +++++++++++++++++-- .../tomcat/SslConnectorCustomizerTests.java | 39 ++++++++++- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index 900e9cb2338..0c23ffeb452 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,6 +23,6 @@ nullabilityPluginVersion=0.0.11 snakeYamlVersion=2.5 springFrameworkVersion=7.0.4-SNAPSHOT springFramework60xVersion=6.0.23 -tomcatVersion=11.0.15 +tomcatVersion=11.0.18 kotlin.stdlib.default.dependency=false diff --git a/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java b/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java index 9b5afd1e6ee..590d3924c60 100644 --- a/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java +++ b/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java @@ -16,6 +16,8 @@ package org.springframework.boot.tomcat; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.apache.catalina.connector.Connector; @@ -25,6 +27,7 @@ import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type; +import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser; import org.jspecify.annotations.Nullable; import org.springframework.boot.ssl.SslBundle; @@ -113,14 +116,24 @@ public class SslConnectorCustomizer { certificate.setCertificateKeyAlias(key.getAlias()); } sslHostConfig.addCertificate(certificate); - if (options.getCiphers() != null) { - String ciphers = StringUtils.arrayToCommaDelimitedString(options.getCiphers()); - sslHostConfig.setCiphers(ciphers); - } + configureCiphers(options, sslHostConfig); configureSslStores(sslHostConfig, certificate, stores); configureEnabledProtocols(sslHostConfig, options); } + private void configureCiphers(SslOptions options, SSLHostConfig sslHostConfig) { + CipherConfiguration cipherConfiguration = CipherConfiguration.from(options); + if (cipherConfiguration != null) { + sslHostConfig.setCiphers(cipherConfiguration.tls12Ciphers); + try { + sslHostConfig.setCipherSuites(cipherConfiguration.tls13Ciphers); + } + catch (Exception ex) { + // Tomcat version without setCipherSuites method. Continue. + } + } + } + private void configureEnabledProtocols(SSLHostConfig sslHostConfig, SslOptions options) { if (options.getEnabledProtocols() != null) { String enabledProtocols = StringUtils.arrayToDelimitedString(options.getEnabledProtocols(), "+"); @@ -147,4 +160,47 @@ public class SslConnectorCustomizer { } } + private static class CipherConfiguration { + + private final String tls12Ciphers; + + private final String tls13Ciphers; + + CipherConfiguration(String tls12Ciphers, String tls13Ciphers) { + this.tls12Ciphers = tls12Ciphers; + this.tls13Ciphers = tls13Ciphers; + } + + static @Nullable CipherConfiguration from(SslOptions options) { + List tls12Ciphers = new ArrayList<>(); + List tls13Ciphers = new ArrayList<>(); + String[] ciphers = options.getCiphers(); + if (ciphers == null || ciphers.length == 0) { + return null; + } + for (String cipher : ciphers) { + if (isTls13(cipher)) { + tls13Ciphers.add(cipher); + } + else { + tls12Ciphers.add(cipher); + } + } + return new CipherConfiguration(StringUtils.collectionToCommaDelimitedString(tls12Ciphers), + StringUtils.collectionToCommaDelimitedString(tls13Ciphers)); + } + + private static boolean isTls13(String cipher) { + try { + return OpenSSLCipherConfigurationParser.isTls13Cipher(cipher); + } + catch (Exception ex) { + // Tomcat version without isTls13Cipher method. Continue, treating all + // ciphers as TLSv1.2 + return false; + } + } + + } + } diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java index 69b49538ce0..af81da18728 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java @@ -23,6 +23,7 @@ import org.apache.catalina.startup.Tomcat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tomcat.util.net.SSLHostConfig; +import org.apache.tomcat.util.net.openssl.ciphers.Cipher; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -73,7 +74,7 @@ class SslConnectorCustomizerTests { @Test @WithPackageResources("test.jks") - void sslCiphersConfiguration() throws Exception { + void tls12CiphersConfiguration() throws Exception { Ssl ssl = new Ssl(); ssl.setKeyStore("classpath:test.jks"); ssl.setKeyStorePassword("secret"); @@ -84,6 +85,42 @@ class SslConnectorCustomizerTests { this.tomcat.start(); SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); assertThat(sslHostConfigs[0].getCiphers()).isEqualTo("ALPHA:BRAVO:CHARLIE"); + assertThat(sslHostConfigs[0].getCipherSuites()).isEmpty(); + } + + @Test + @WithPackageResources("test.jks") + void tls13CiphersConfiguration() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyStore("classpath:test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setCiphers(new String[] { Cipher.TLS_AES_128_CCM_SHA256.getOpenSSLAlias(), + Cipher.TLS_AES_256_GCM_SHA384.getOpenSSLAlias() }); + Connector connector = this.tomcat.getConnector(); + SslConnectorCustomizer customizer = new SslConnectorCustomizer(this.logger, connector, ssl.getClientAuth()); + customizer.customize(WebServerSslBundle.get(ssl), Collections.emptyMap()); + this.tomcat.start(); + SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); + assertThat(sslHostConfigs[0].getCiphers()).isEmpty(); + assertThat(sslHostConfigs[0].getCipherSuites()).isEqualTo("TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384"); + } + + @Test + @WithPackageResources("test.jks") + void mixedTls12AndTls13CiphersConfiguration() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyStore("classpath:test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setCiphers(new String[] { Cipher.TLS_AES_128_CCM_SHA256.getOpenSSLAlias(), + Cipher.TLS_DH_DSS_WITH_AES_128_CBC_SHA256.getOpenSSLAlias(), + Cipher.TLS_AES_256_GCM_SHA384.getOpenSSLAlias() }); + Connector connector = this.tomcat.getConnector(); + SslConnectorCustomizer customizer = new SslConnectorCustomizer(this.logger, connector, ssl.getClientAuth()); + customizer.customize(WebServerSslBundle.get(ssl), Collections.emptyMap()); + this.tomcat.start(); + SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); + assertThat(sslHostConfigs[0].getCiphers()).isEqualTo("DH-DSS-AES128-SHA256"); + assertThat(sslHostConfigs[0].getCipherSuites()).isEqualTo("TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384"); } @Test