Skip to content

Commit 19cf503

Browse files
committed
Align with Servlet 6.0 and introduce support for Jakarta WebSocket 2.1
Includes corresponding build upgrade to Tomcat 10.1.1 and Undertow 2.3.0 (while retaining runtime compatibility with Tomcat 10.0 and Undertow 2.2) Closes gh-29435 Closes gh-29436
1 parent 4b22a4a commit 19cf503

File tree

37 files changed

+289
-340
lines changed

37 files changed

+289
-340
lines changed

framework-docs/src/docs/asciidoc/overview.adoc

+4-3
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,10 @@ by the Spring Framework. Originally, those were based on common `javax` packages
7878

7979
As of Spring Framework 6.0, Spring has been upgraded to the Jakarta EE 9 level
8080
(e.g. Servlet 5.0+, JPA 3.0+), based on the `jakarta` namespace instead of the
81-
traditional `javax` packages. With EE 9 as the minimum, Spring is prepared to
82-
provide out-of-the-box support for further API evolution in EE 10+ once available.
83-
This makes Spring Framework 6 fully compatible with e.g. Tomcat 10+ and Jetty 11+.
81+
traditional `javax` packages. With EE 9 as the minimum and EE 10 supported already,
82+
Spring is prepared to provide out-of-the-box support for the further evolution of
83+
the Jakarta EE APIs. Spring Framework 6.0 is fully compatible with Tomcat 10.1,
84+
Jetty 11 and Undertow 2.3 as web servers, and also with Hibernate ORM 6.1.
8485

8586
Over time, the role of Java/Jakarta EE in application development has evolved. In the
8687
early days of J2EE and Spring, applications were created to be deployed to an application

framework-platform/framework-platform.gradle

+14-13
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ dependencies {
5454
api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE")
5555
api("io.reactivex.rxjava3:rxjava:3.1.5")
5656
api("io.smallrye.reactive:mutiny:1.7.0")
57-
api("io.undertow:undertow-core:2.2.19.Final")
58-
api("io.undertow:undertow-servlet-jakarta:2.2.19.Final")
59-
api("io.undertow:undertow-websockets-jsr-jakarta:2.2.19.Final")
57+
api("io.undertow:undertow-core:2.3.0.Final")
58+
api("io.undertow:undertow-servlet:2.3.0.Final")
59+
api("io.undertow:undertow-websockets-jsr:2.3.0.Final")
6060
api("io.vavr:vavr:0.10.4")
6161
api("jakarta.activation:jakarta.activation-api:2.0.1")
6262
api("jakarta.annotation:jakarta.annotation-api:2.0.0")
@@ -73,12 +73,13 @@ dependencies {
7373
api("jakarta.mail:jakarta.mail-api:2.0.1")
7474
api("jakarta.persistence:jakarta.persistence-api:3.0.0")
7575
api("jakarta.resource:jakarta.resource-api:2.0.0")
76-
api("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:2.0.0")
77-
api("jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.0.0")
78-
api("jakarta.servlet:jakarta.servlet-api:5.0.0")
79-
api("jakarta.transaction:jakarta.transaction-api:2.0.0")
80-
api("jakarta.validation:jakarta.validation-api:3.0.0")
81-
api("jakarta.websocket:jakarta.websocket-api:2.0.0")
76+
api("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0")
77+
api("jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.0")
78+
api("jakarta.servlet:jakarta.servlet-api:6.0.0")
79+
api("jakarta.transaction:jakarta.transaction-api:2.0.1")
80+
api("jakarta.validation:jakarta.validation-api:3.0.2")
81+
api("jakarta.websocket:jakarta.websocket-api:2.1.0")
82+
api("jakarta.websocket:jakarta.websocket-client-api:2.1.0")
8283
api("jakarta.xml.bind:jakarta.xml.bind-api:3.0.1")
8384
api("javax.cache:cache-api:1.1.1")
8485
api("javax.money:money-api:1.1")
@@ -97,10 +98,10 @@ dependencies {
9798
api("org.apache.httpcomponents.client5:httpclient5:5.1.3")
9899
api("org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3")
99100
api("org.apache.poi:poi-ooxml:5.2.2")
100-
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.0")
101-
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.0")
102-
api("org.apache.tomcat:tomcat-util:10.0.22")
103-
api("org.apache.tomcat:tomcat-websocket:10.0.22")
101+
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.1")
102+
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.1")
103+
api("org.apache.tomcat:tomcat-util:10.1.1")
104+
api("org.apache.tomcat:tomcat-websocket:10.1.1")
104105
api("org.aspectj:aspectjrt:1.9.9.1")
105106
api("org.aspectj:aspectjtools:1.9.9.1")
106107
api("org.aspectj:aspectjweaver:1.9.9.1")

spring-test/spring-test.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ dependencies {
2323
optional("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api")
2424
optional("jakarta.xml.bind:jakarta.xml.bind-api")
2525
optional("jakarta.websocket:jakarta.websocket-api")
26+
optional("jakarta.websocket:jakarta.websocket-client-api")
2627
optional("junit:junit")
2728
optional("org.apache.tomcat.embed:tomcat-embed-core")
28-
optional("org.junit.platform:junit-platform-launcher") // for AOT processing
29+
optional("org.junit.platform:junit-platform-launcher") // for AOT processing
2930
optional("org.junit.jupiter:junit-jupiter-api")
3031
optional("org.testng:testng")
3132
optional("org.aspectj:aspectjweaver")

spring-test/src/main/java/org/springframework/mock/web/MockCookie.java

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
* @author Sam Brannen
3737
* @since 5.1
3838
*/
39+
@SuppressWarnings("removal")
3940
public class MockCookie extends Cookie {
4041

4142
private static final long serialVersionUID = 4312531139502726325L;

spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java

+35-14
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import jakarta.servlet.AsyncContext;
4747
import jakarta.servlet.DispatcherType;
4848
import jakarta.servlet.RequestDispatcher;
49+
import jakarta.servlet.ServletConnection;
4950
import jakarta.servlet.ServletContext;
5051
import jakarta.servlet.ServletException;
5152
import jakarta.servlet.ServletInputStream;
@@ -79,7 +80,7 @@
7980
* is {@link Locale#ENGLISH}. This value can be changed via {@link #addPreferredLocale}
8081
* or {@link #setPreferredLocales}.
8182
*
82-
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
83+
* <p>As of Spring 6.0, this set of mocks is designed on a Servlet 6.0 baseline.
8384
*
8485
* @author Juergen Hoeller
8586
* @author Rod Johnson
@@ -878,12 +879,6 @@ public RequestDispatcher getRequestDispatcher(String path) {
878879
return new MockRequestDispatcher(path);
879880
}
880881

881-
@Override
882-
@Deprecated
883-
public String getRealPath(String path) {
884-
return this.servletContext.getRealPath(path);
885-
}
886-
887882
public void setRemotePort(int remotePort) {
888883
this.remotePort = remotePort;
889884
}
@@ -970,6 +965,38 @@ public DispatcherType getDispatcherType() {
970965
return this.dispatcherType;
971966
}
972967

968+
@Override
969+
public String getRequestId() {
970+
return "";
971+
}
972+
973+
@Override
974+
public String getProtocolRequestId() {
975+
return "";
976+
}
977+
978+
@Override
979+
public ServletConnection getServletConnection() {
980+
return new ServletConnection() {
981+
@Override
982+
public String getConnectionId() {
983+
return MockHttpServletRequest.this.getRequestId();
984+
}
985+
@Override
986+
public String getProtocol() {
987+
return MockHttpServletRequest.this.getProtocol();
988+
}
989+
@Override
990+
public String getProtocolConnectionId() {
991+
return MockHttpServletRequest.this.getProtocolRequestId();
992+
}
993+
@Override
994+
public boolean isSecure() {
995+
return MockHttpServletRequest.this.isSecure();
996+
}
997+
};
998+
}
999+
9731000

9741001
// ---------------------------------------------------------------------
9751002
// HttpServletRequest interface
@@ -1183,7 +1210,7 @@ public String getPathInfo() {
11831210
@Override
11841211
@Nullable
11851212
public String getPathTranslated() {
1186-
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
1213+
return (this.pathInfo != null ? this.servletContext.getRealPath(this.pathInfo) : null);
11871214
}
11881215

11891216
public void setContextPath(String contextPath) {
@@ -1352,12 +1379,6 @@ public boolean isRequestedSessionIdFromURL() {
13521379
return this.requestedSessionIdFromURL;
13531380
}
13541381

1355-
@Override
1356-
@Deprecated
1357-
public boolean isRequestedSessionIdFromUrl() {
1358-
return isRequestedSessionIdFromURL();
1359-
}
1360-
13611382
@Override
13621383
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
13631384
throw new UnsupportedOperationException();

spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java

+2-22
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
/**
5454
* Mock implementation of the {@link jakarta.servlet.http.HttpServletResponse} interface.
5555
*
56-
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
56+
* <p>As of Spring 6.0, this set of mocks is designed on a Servlet 6.0 baseline.
5757
*
5858
* @author Juergen Hoeller
5959
* @author Rod Johnson
@@ -413,6 +413,7 @@ public void addCookie(Cookie cookie) {
413413
doAddHeaderValue(HttpHeaders.SET_COOKIE, getCookieHeader(cookie), false);
414414
}
415415

416+
@SuppressWarnings("removal")
416417
private String getCookieHeader(Cookie cookie) {
417418
StringBuilder buf = new StringBuilder();
418419
buf.append(cookie.getName()).append('=').append(cookie.getValue() == null ? "" : cookie.getValue());
@@ -572,18 +573,6 @@ public String encodeRedirectURL(String url) {
572573
return encodeURL(url);
573574
}
574575

575-
@Override
576-
@Deprecated
577-
public String encodeUrl(String url) {
578-
return encodeURL(url);
579-
}
580-
581-
@Override
582-
@Deprecated
583-
public String encodeRedirectUrl(String url) {
584-
return encodeRedirectURL(url);
585-
}
586-
587576
@Override
588577
public void sendError(int status, String errorMessage) throws IOException {
589578
Assert.state(!isCommitted(), "Cannot set error status - response is already committed");
@@ -758,15 +747,6 @@ public void setStatus(int status) {
758747
}
759748
}
760749

761-
@Override
762-
@Deprecated
763-
public void setStatus(int status, String errorMessage) {
764-
if (!this.isCommitted()) {
765-
this.status = status;
766-
this.errorMessage = errorMessage;
767-
}
768-
}
769-
770750
@Override
771751
public int getStatus() {
772752
return this.status;

spring-test/src/main/java/org/springframework/mock/web/MockHttpSession.java

+2-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,12 +32,11 @@
3232

3333
import org.springframework.lang.Nullable;
3434
import org.springframework.util.Assert;
35-
import org.springframework.util.StringUtils;
3635

3736
/**
3837
* Mock implementation of the {@link jakarta.servlet.http.HttpSession} interface.
3938
*
40-
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
39+
* <p>As of Spring 6.0, this set of mocks is designed on a Servlet 6.0 baseline.
4140
*
4241
* @author Juergen Hoeller
4342
* @author Rod Johnson
@@ -148,35 +147,19 @@ public int getMaxInactiveInterval() {
148147
return this.maxInactiveInterval;
149148
}
150149

151-
@Override
152-
public jakarta.servlet.http.HttpSessionContext getSessionContext() {
153-
throw new UnsupportedOperationException("getSessionContext");
154-
}
155-
156150
@Override
157151
public Object getAttribute(String name) {
158152
assertIsValid();
159153
Assert.notNull(name, "Attribute name must not be null");
160154
return this.attributes.get(name);
161155
}
162156

163-
@Override
164-
public Object getValue(String name) {
165-
return getAttribute(name);
166-
}
167-
168157
@Override
169158
public Enumeration<String> getAttributeNames() {
170159
assertIsValid();
171160
return Collections.enumeration(new LinkedHashSet<>(this.attributes.keySet()));
172161
}
173162

174-
@Override
175-
public String[] getValueNames() {
176-
assertIsValid();
177-
return StringUtils.toStringArray(this.attributes.keySet());
178-
}
179-
180163
@Override
181164
public void setAttribute(String name, @Nullable Object value) {
182165
assertIsValid();
@@ -197,11 +180,6 @@ public void setAttribute(String name, @Nullable Object value) {
197180
}
198181
}
199182

200-
@Override
201-
public void putValue(String name, Object value) {
202-
setAttribute(name, value);
203-
}
204-
205183
@Override
206184
public void removeAttribute(String name) {
207185
assertIsValid();
@@ -212,11 +190,6 @@ public void removeAttribute(String name) {
212190
}
213191
}
214192

215-
@Override
216-
public void removeValue(String name) {
217-
removeAttribute(name);
218-
}
219-
220193
/**
221194
* Clear all of this session's attributes.
222195
*/

spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@
4343
* Mock implementation of the
4444
* {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface.
4545
*
46-
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
46+
* <p>As of Spring 6.0, this set of mocks is designed on a Servlet 6.0 baseline.
4747
*
4848
* <p>Useful for testing application controllers that access multipart uploads.
4949
* {@link MockMultipartFile} can be used to populate these mock requests with files.

spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@
6060
/**
6161
* Mock implementation of the {@link jakarta.servlet.ServletContext} interface.
6262
*
63-
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
63+
* <p>As of Spring 6.0, this set of mocks is designed on a Servlet 6.0 baseline.
6464
*
6565
* <p>Compatible with Servlet 3.1 but can be configured to expose a specific version
6666
* through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.1.
@@ -430,36 +430,11 @@ public void setDefaultServletName(String defaultServletName) {
430430
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
431431
}
432432

433-
@Deprecated
434-
@Override
435-
@Nullable
436-
public Servlet getServlet(String name) {
437-
return null;
438-
}
439-
440-
@Override
441-
@Deprecated
442-
public Enumeration<Servlet> getServlets() {
443-
return Collections.enumeration(Collections.emptySet());
444-
}
445-
446-
@Override
447-
@Deprecated
448-
public Enumeration<String> getServletNames() {
449-
return Collections.enumeration(Collections.emptySet());
450-
}
451-
452433
@Override
453434
public void log(String message) {
454435
logger.info(message);
455436
}
456437

457-
@Override
458-
@Deprecated
459-
public void log(Exception ex, String message) {
460-
logger.info(message, ex);
461-
}
462-
463438
@Override
464439
public void log(String message, Throwable ex) {
465440
logger.info(message, ex);

0 commit comments

Comments
 (0)