diff --git a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle
index 52c1e178e1b..8fe601a425b 100644
--- a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle
+++ b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle
@@ -23,7 +23,7 @@ apply plugin: 'io.spring.dependency-management'
// tag::dependencies[]
dependencies {
- implementation('org.springframework.boot:spring-boot-starter-web')
- providedRuntime('org.springframework.boot:spring-boot-tomcat-runtime')
+ implementation('org.springframework.boot:spring-boot-starter-webmvc')
+ providedRuntime('org.springframework.boot:spring-boot-starter-tomcat-runtime')
}
// end::dependencies[]
diff --git a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle.kts b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle.kts
index d59ac9d0cdb..60f7df8a934 100644
--- a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle.kts
+++ b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/examples/packaging/war-container-dependency.gradle.kts
@@ -8,6 +8,6 @@ apply(plugin = "io.spring.dependency-management")
// tag::dependencies[]
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
- providedRuntime("org.springframework.boot:spring-boot-tomcat-runtime")
+ providedRuntime("org.springframework.boot:spring-boot-starter-tomcat-runtime")
}
// end::dependencies[]
diff --git a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging.adoc b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging.adoc
index a68caa60f55..af873a18b1f 100644
--- a/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging.adoc
+++ b/build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging.adoc
@@ -27,7 +27,7 @@ The `assemble` task is automatically configured to depend upon the `bootWar` tas
=== Packaging Executable and Deployable Wars
A war file can be packaged such that it can be executed using `java -jar` and deployed to an external container.
-To do so, the embedded servlet runtime should be added to the `providedRuntime` configuration, for example:
+To do so, the embedded servlet container runtime should be added to the `providedRuntime` configuration, for example:
[tabs]
======
@@ -45,7 +45,7 @@ include::example$packaging/war-container-dependency.gradle.kts[tags=dependencies
----
======
-This ensures that the runtime is packaged in the war file's `WEB-INF/lib-provided` directory from where it will not conflict with the external container's own classes.
+This ensures that the runtime jars are packaged in the war file's `WEB-INF/lib-provided` directory from where they will not conflict with the external container's own classes.
NOTE: `providedRuntime` is preferred to Gradle's `compileOnly` configuration as, among other limitations, `compileOnly` dependencies are not on the test classpath so any web-based integration tests will fail.
diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/traditional-deployment.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/traditional-deployment.adoc
index ea91618e790..a81644d7e23 100644
--- a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/traditional-deployment.adoc
+++ b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/deployment/traditional-deployment.adoc
@@ -33,9 +33,9 @@ apply plugin: 'war'
----
The final step in the process is to ensure that the embedded servlet container does not interfere with the servlet container to which the war file is deployed.
-To do so, you need to mark the embedded servlet runtime dependency as being provided.
-If you use Maven, the following example marks the servlet runtime (Tomcat, in this case) as being provided:
+For Maven, you need to mark the embedded servlet container dependency as being `provided`.
+For example:
[source,xml]
----
@@ -43,20 +43,21 @@ If you use Maven, the following example marks the servlet runtime (Tomcat, in th
org.springframework.boot
- spring-boot-tomcat-runtime
+ spring-boot-starter-tomcat
provided
----
-If you use Gradle, the following example marks the servlet runtime (Tomcat, in this case) as being provided:
+If you use Gradle, you need to move only the runtime dependencies into the `providedRuntime` configuration.
+For example:
[source,gradle]
----
dependencies {
// ...
- providedRuntime 'org.springframework.boot:spring-boot-tomcat-runtime'
+ providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat-runtime'
// ...
}
----
diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc
index b61c5659726..dfefc16d879 100644
--- a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc
+++ b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/webserver.adoc
@@ -18,13 +18,18 @@ Many Spring Boot starters include default embedded containers.
When switching to a different HTTP server, you need to swap the default dependencies for those that you need instead.
To help with this process, Spring Boot provides a separate starter for each of the supported HTTP servers.
-The following Maven example shows how to exclude Tomcat and include Jetty for Spring MVC:
+The following example shows how to exclude Tomcat and include Jetty for Spring MVC:
+[tabs]
+======
+
+Maven::
++
[source,xml]
----
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
@@ -39,23 +44,70 @@ The following Maven example shows how to exclude Tomcat and include Jetty for Sp
spring-boot-starter-jetty
----
++
-The following Gradle example configures the necessary dependencies and a {url-gradle-docs}/resolution_rules.html#sec:module_replacement[module replacement] to use Tomcat in place of Reactor Netty for Spring WebFlux:
-
+Gradle::
++
[source,gradle]
----
dependencies {
- implementation "org.springframework.boot:spring-boot-starter-tomcat"
- implementation "org.springframework.boot:spring-boot-starter-webflux"
- modules {
- module("org.springframework.boot:spring-boot-starter-reactor-netty") {
- replacedBy("org.springframework.boot:spring-boot-starter-tomcat", "Use Tomcat instead of Reactor Netty")
- }
+ implementation('org.springframework.boot:spring-boot-starter-webmvc') {
+ // Exclude the Tomcat dependency
+ exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
+ // Use Jetty instead
+ implementation "org.springframework.boot:spring-boot-starter-jetty"
}
----
++
+======
+
+If you are creating a war file, you can use a similar approach, but you must indicate provided dependencies:
+
+
+[tabs]
+======
+
+Maven::
++
+[source,xml]
+----
+
+ org.springframework.boot
+ spring-boot-starter-webmvc
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jetty
+ provided
+
+----
++
-NOTE: `spring-boot-starter-reactor-netty` is required to use the javadoc:org.springframework.web.reactive.function.client.WebClient[] class, so you may need to keep a dependency on Netty even when you need to include a different HTTP server.
+Gradle::
++
+[source,gradle]
+----
+dependencies {
+ implementation('org.springframework.boot:spring-boot-starter-webmvc') {
+ // Exclude the Tomcat dependency
+ exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
+ }
+ // Use Jetty instead
+ implementation "org.springframework.boot:spring-boot-starter-jetty"
+ providedRuntime "org.springframework.boot:spring-boot-starter-jetty-runtime"
+}
+----
++
+======
diff --git a/module/spring-boot-jetty/build.gradle b/module/spring-boot-jetty/build.gradle
index 9faab9a59d4..25e314dace7 100644
--- a/module/spring-boot-jetty/build.gradle
+++ b/module/spring-boot-jetty/build.gradle
@@ -25,17 +25,20 @@ plugins {
description = "Spring Boot Jetty"
dependencies {
- api(project(":module:spring-boot-jetty-runtime"))
api(project(":module:spring-boot-web-server"))
- api("jakarta.servlet:jakarta.servlet-api")
- api("jakarta.websocket:jakarta.websocket-api")
- api("jakarta.websocket:jakarta.websocket-client-api")
+ api("org.eclipse.jetty.ee11:jetty-ee11-servlets")
+ api("org.eclipse.jetty.ee11:jetty-ee11-webapp")
+
+ implementation("org.eclipse.jetty.compression:jetty-compression-server")
+ implementation("org.eclipse.jetty.compression:jetty-compression-gzip")
optional(project(":core:spring-boot-autoconfigure"))
optional(project(":module:spring-boot-actuator-autoconfigure"))
optional(project(":module:spring-boot-micrometer-metrics"))
optional("org.apache.tomcat.embed:tomcat-embed-jasper")
optional("org.eclipse.jetty:jetty-alpn-conscrypt-server")
+ optional("org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-jakarta-server")
+ optional("org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-jetty-server")
optional("org.eclipse.jetty.http2:jetty-http2-server")
optional("org.springframework:spring-webflux")
diff --git a/module/spring-boot-tomcat/build.gradle b/module/spring-boot-tomcat/build.gradle
index 1ccd8d30c73..252f953b264 100644
--- a/module/spring-boot-tomcat/build.gradle
+++ b/module/spring-boot-tomcat/build.gradle
@@ -32,13 +32,18 @@ configurations {
dependencies {
api(project(":module:spring-boot-web-server"))
- api(project(":module:spring-boot-tomcat-runtime"))
+ api("org.apache.tomcat.embed:tomcat-embed-core") {
+ exclude group: "org.apache.tomcat", module: "tomcat-annotations-api"
+ }
optional(project(":core:spring-boot-autoconfigure"))
optional(project(":module:spring-boot-actuator-autoconfigure"))
optional(project(":module:spring-boot-micrometer-metrics"))
optional("io.micrometer:micrometer-core")
optional("org.apache.tomcat.embed:tomcat-embed-jasper")
+ optional("org.apache.tomcat.embed:tomcat-embed-websocket") {
+ exclude group: "org.apache.tomcat", module: "tomcat-annotations-api"
+ }
optional("org.springframework:spring-webflux")
runtimeOnly("jakarta.annotation:jakarta.annotation-api")
diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle
index 00b53bdfa3c..73d35ad6117 100644
--- a/platform/spring-boot-dependencies/build.gradle
+++ b/platform/spring-boot-dependencies/build.gradle
@@ -2051,7 +2051,6 @@ bom {
"spring-boot-jdbc-test",
"spring-boot-jersey",
"spring-boot-jetty",
- "spring-boot-jetty-runtime",
"spring-boot-jms",
"spring-boot-jooq",
"spring-boot-jooq-test",
@@ -2180,6 +2179,7 @@ bom {
"spring-boot-starter-jersey",
"spring-boot-starter-jersey-test",
"spring-boot-starter-jetty",
+ "spring-boot-starter-jetty-runtime",
"spring-boot-starter-jms",
"spring-boot-starter-jms-test",
"spring-boot-starter-jooq",
@@ -2245,6 +2245,7 @@ bom {
"spring-boot-starter-thymeleaf",
"spring-boot-starter-thymeleaf-test",
"spring-boot-starter-tomcat",
+ "spring-boot-starter-tomcat-runtime",
"spring-boot-starter-validation",
"spring-boot-starter-validation-test",
"spring-boot-starter-web",
@@ -2266,7 +2267,6 @@ bom {
"spring-boot-testcontainers",
"spring-boot-thymeleaf",
"spring-boot-tomcat",
- "spring-boot-tomcat-runtime",
"spring-boot-transaction",
"spring-boot-validation",
"spring-boot-web-server",
diff --git a/settings.gradle b/settings.gradle
index 584dce4e0f9..3d3ff598b5a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -137,7 +137,6 @@ include "module:spring-boot-jdbc"
include "module:spring-boot-jdbc-test"
include "module:spring-boot-jersey"
include "module:spring-boot-jetty"
-include "module:spring-boot-jetty-runtime"
include "module:spring-boot-jms"
include "module:spring-boot-jooq"
include "module:spring-boot-jooq-test"
@@ -188,7 +187,6 @@ include "module:spring-boot-sql"
include "module:spring-boot-test-classic-modules"
include "module:spring-boot-thymeleaf"
include "module:spring-boot-tomcat"
-include "module:spring-boot-tomcat-runtime"
include "module:spring-boot-transaction"
include "module:spring-boot-validation"
include "module:spring-boot-web-server"
@@ -283,6 +281,7 @@ include "starter:spring-boot-starter-jdbc-test"
include "starter:spring-boot-starter-jersey"
include "starter:spring-boot-starter-jersey-test"
include "starter:spring-boot-starter-jetty"
+include "starter:spring-boot-starter-jetty-runtime"
include "starter:spring-boot-starter-jms"
include "starter:spring-boot-starter-jms-test"
include "starter:spring-boot-starter-jooq"
@@ -349,6 +348,7 @@ include "starter:spring-boot-starter-test-classic"
include "starter:spring-boot-starter-thymeleaf"
include "starter:spring-boot-starter-thymeleaf-test"
include "starter:spring-boot-starter-tomcat"
+include "starter:spring-boot-starter-tomcat-runtime"
include "starter:spring-boot-starter-validation"
include "starter:spring-boot-starter-validation-test"
include "starter:spring-boot-starter-web"
diff --git a/smoke-test/spring-boot-smoke-test-tomcat-jsp/build.gradle b/smoke-test/spring-boot-smoke-test-tomcat-jsp/build.gradle
index d455ac5b6e4..738079232f7 100644
--- a/smoke-test/spring-boot-smoke-test-tomcat-jsp/build.gradle
+++ b/smoke-test/spring-boot-smoke-test-tomcat-jsp/build.gradle
@@ -29,7 +29,7 @@ configurations {
dependencies {
implementation(project(":starter:spring-boot-starter-webmvc"))
- providedRuntime(project(":module:spring-boot-tomcat-runtime"))
+ providedRuntime(project(":starter:spring-boot-starter-tomcat-runtime"))
providedRuntime("org.glassfish.web:jakarta.servlet.jsp.jstl")
providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")
diff --git a/smoke-test/spring-boot-smoke-test-traditional/build.gradle b/smoke-test/spring-boot-smoke-test-traditional/build.gradle
index 9fa743acf01..e3c2a1fcf52 100644
--- a/smoke-test/spring-boot-smoke-test-traditional/build.gradle
+++ b/smoke-test/spring-boot-smoke-test-traditional/build.gradle
@@ -27,9 +27,10 @@ configurations {
}
dependencies {
- implementation(project(":starter:spring-boot-starter-webmvc"))
+ implementation(project(":starter:spring-boot-starter"))
+ implementation(project(":module:spring-boot-webmvc"))
- providedRuntime(project(":module:spring-boot-tomcat-runtime"))
+ providedRuntime(project(":starter:spring-boot-starter-tomcat-runtime"))
providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")
testImplementation(project(":module:spring-boot-resttestclient"))
diff --git a/smoke-test/spring-boot-smoke-test-web-jsp/build.gradle b/smoke-test/spring-boot-smoke-test-web-jsp/build.gradle
index dd6bd1fe88a..3d20bf9cd7b 100644
--- a/smoke-test/spring-boot-smoke-test-web-jsp/build.gradle
+++ b/smoke-test/spring-boot-smoke-test-web-jsp/build.gradle
@@ -29,7 +29,7 @@ configurations {
dependencies {
implementation(project(":starter:spring-boot-starter-webmvc"))
- providedRuntime(project(":module:spring-boot-tomcat-runtime"))
+ providedRuntime(project(":starter:spring-boot-starter-tomcat-runtime"))
providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")
providedRuntime("org.glassfish.web:jakarta.servlet.jsp.jstl")
diff --git a/smoke-test/spring-boot-smoke-test-web-static/build.gradle b/smoke-test/spring-boot-smoke-test-web-static/build.gradle
index 47c4e5e991d..61ea11439e5 100644
--- a/smoke-test/spring-boot-smoke-test-web-static/build.gradle
+++ b/smoke-test/spring-boot-smoke-test-web-static/build.gradle
@@ -29,7 +29,7 @@ configurations {
dependencies {
implementation(project(":starter:spring-boot-starter-webmvc"))
- providedRuntime(project(":module:spring-boot-tomcat-runtime"))
+ providedRuntime( project(":starter:spring-boot-starter-tomcat-runtime"))
runtimeOnly("org.webjars:bootstrap:3.0.3")
runtimeOnly("org.webjars:jquery:2.0.3-1")
diff --git a/module/spring-boot-jetty-runtime/build.gradle b/starter/spring-boot-starter-jetty-runtime/build.gradle
similarity index 63%
rename from module/spring-boot-jetty-runtime/build.gradle
rename to starter/spring-boot-starter-jetty-runtime/build.gradle
index a911b1e52d2..188ee683708 100644
--- a/module/spring-boot-jetty-runtime/build.gradle
+++ b/starter/spring-boot-starter-jetty-runtime/build.gradle
@@ -15,34 +15,31 @@
*/
plugins {
- id "java-library"
- id "org.springframework.boot.deployed"
+ id "org.springframework.boot.starter"
}
-description = "Spring Boot Jetty Runtime"
+description = "Starter for the Jetty runtime"
dependencies {
- api("org.apache.tomcat.embed:tomcat-embed-el")
- api("org.eclipse.jetty.compression:jetty-compression-gzip") {
- exclude group: "org.slf4j", module: "slf4j-api"
- }
- api("org.eclipse.jetty.compression:jetty-compression-server") {
- exclude group: "org.slf4j", module: "slf4j-api"
+ api(project(":module:spring-boot-jetty")) {
+ transitive = false
}
- api("org.eclipse.jetty.ee11:jetty-ee11-servlets") {
- exclude group: "org.slf4j", module: "slf4j-api"
- }
- api("org.eclipse.jetty.ee11:jetty-ee11-webapp") {
- exclude group: "org.slf4j", module: "slf4j-api"
+ api(project(":module:spring-boot-web-server")) {
+ transitive = false
}
+ api("jakarta.servlet:jakarta.servlet-api")
+ api("jakarta.websocket:jakarta.websocket-api")
+ api("jakarta.websocket:jakarta.websocket-client-api")
+ api("org.apache.tomcat.embed:tomcat-embed-el")
api("org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-jakarta-server") {
exclude group: "jakarta.el", module: "jakarta.el-api"
exclude group: "org.eclipse.jetty", module: "jetty-jndi"
- exclude group: "org.slf4j", module: "slf4j-api"
+ exclude group: "org.slf4j", module: "slf4j-api"
+ exclude group: "jakarta.annotation", module: "jakarta.annotation-api"
}
api("org.eclipse.jetty.ee11.websocket:jetty-ee11-websocket-jetty-server") {
exclude group: "jakarta.el", module: "jakarta.el-api"
exclude group: "org.eclipse.jetty", module: "jetty-jndi"
- exclude group: "org.slf4j", module: "slf4j-api"
+ exclude group: "org.slf4j", module: "slf4j-api"
}
}
diff --git a/starter/spring-boot-starter-jetty/build.gradle b/starter/spring-boot-starter-jetty/build.gradle
index 4cdab32a453..3f401bca10d 100644
--- a/starter/spring-boot-starter-jetty/build.gradle
+++ b/starter/spring-boot-starter-jetty/build.gradle
@@ -22,5 +22,10 @@ description = "Starter for using Jetty as the embedded servlet container"
dependencies {
api(project(":starter:spring-boot-starter"))
+ api(project(":starter:spring-boot-starter-jetty-runtime"))
+
api(project(":module:spring-boot-jetty"))
+
+ api("org.slf4j:slf4j-api")
+ api("jakarta.annotation:jakarta.annotation-api")
}
diff --git a/module/spring-boot-tomcat-runtime/build.gradle b/starter/spring-boot-starter-tomcat-runtime/build.gradle
similarity index 77%
rename from module/spring-boot-tomcat-runtime/build.gradle
rename to starter/spring-boot-starter-tomcat-runtime/build.gradle
index cbe5ca0a1b5..f7f2a06c8cf 100644
--- a/module/spring-boot-tomcat-runtime/build.gradle
+++ b/starter/spring-boot-starter-tomcat-runtime/build.gradle
@@ -15,13 +15,19 @@
*/
plugins {
- id "java-library"
- id "org.springframework.boot.deployed"
+ id "org.springframework.boot.starter"
}
-description = "Spring Boot Tomcat Runtime"
+description = "Starter for the Tomcat runtime"
dependencies {
+ api(project(":module:spring-boot-tomcat")) {
+ transitive = false
+ }
+ api(project(":module:spring-boot-web-server")) {
+ transitive = false
+ }
+ api("jakarta.annotation:jakarta.annotation-api")
api("org.apache.tomcat.embed:tomcat-embed-core") {
exclude group: "org.apache.tomcat", module: "tomcat-annotations-api"
}
diff --git a/starter/spring-boot-starter-tomcat/build.gradle b/starter/spring-boot-starter-tomcat/build.gradle
index 254a50eda20..e4ab73b3f82 100644
--- a/starter/spring-boot-starter-tomcat/build.gradle
+++ b/starter/spring-boot-starter-tomcat/build.gradle
@@ -18,10 +18,11 @@ plugins {
id "org.springframework.boot.starter"
}
-description = "Starter for using Tomcat"
+description = "Starter for using Tomcat as the embedded servlet container"
dependencies {
api(project(":starter:spring-boot-starter"))
+ api(project(":starter:spring-boot-starter-tomcat-runtime"))
+
api(project(":module:spring-boot-tomcat"))
- api("jakarta.annotation:jakarta.annotation-api")
}
diff --git a/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-executableWarApp.gradle b/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-executableWarApp.gradle
index 7b158712621..72a1fa79368 100644
--- a/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-executableWarApp.gradle
+++ b/system-test/spring-boot-image-system-tests/src/systemTest/resources/org/springframework/boot/image/paketo/PaketoBuilderTests-executableWarApp.gradle
@@ -38,7 +38,7 @@ repositories {
dependencies {
implementation("org.springframework.boot:spring-boot-starter-webmvc:{bootVersion}")
- providedRuntime("org.springframework.boot:spring-boot-tomcat-runtime:{bootVersion}")
+ providedRuntime("org.springframework.boot:spring-boot-starter-tomcat-runtime:{bootVersion}")
}
bootWar {