⭐ New Features
- Add null check for ExceptionHandlerMethodResolvers #26339
- ClassNotFoundException: ExchangeFunction when using WebTestClient with Spring MVC #26308
- Early support for JDK 17 #26307
- Assertion error details lost in rethrow in assertWithDiagnostics #26303
- Update ReactiveAdapterRegistry to do classpath checks at class initialization #26295
- Problem with
@Schedule
with Quartz features in CronExpression #26289 - Make use of abortOnRequest in Jetty Reactive HttpClient #26287
- Update OncePerRequestFilter.isAsyncDispatch to use HttpServletRequest.getDispatcherType() #26282
- Introduce computeAttribute() in AttributeAccessor #26281
- Translate PostgreSQL code 21000 (cardinality_violation) #26276
- Consistent type resolution handling for NullBean #26271
- Defensively handle loadClass null result in BeanUtils.findEditorByConvention (against misbehaving ClassLoader impl such as in the GWT JettyLauncher) #26252
- Subscriber context not propagated to WebSocketHandler for Tomcat websockets #26210
- Introduce ApplicationEvents abstraction to capture application events published during a test #25616
- Spring AOP should not apply UndeclaredThrowableException to checked exceptions from Kotlin methods #23844
🪲 Bug Fixes
- Cannot remove headers from httpHeaders.keySet() in WebFlux #26361
- ClassCastException handling at SimpleApplicationEventMulticaster of payload items #26349
- DefaultPartHttpMessageReader creates live resources that won't be shut down #26347
- Sending empty Flux to RSocket channel causes DecodingException: JSON decoding error: No content to map due to end-of-input #26344
- Fix implementation of isOpen() in ReactorNettyWebSocketSession #26341
- Remove obsolete commandName attribute in spring-form.tld #26337
- The response has a duplicate "Content-Length" header when get by range header #26330
@ExceptionHandler
methods not invokable if matched on exception's cause level > 1 #26317- Switch to PathPatternParser for Spring MVC breaks welcome page auto configuration #26318
- CronExpression cannot parse combination of step values #26313
- Fix JdbcOperations.queryForObject/queryForList extensions #26312
- ClassCastException during websocket upgrade for mutated request #26304
- kotlinx.serialization should not be used for Java interfaces implemented by Java classes #26298
- NettyHeadersAdapter.add() accepts
@Nullable
value but throws NullPointerException #26274 - Lots of boundedElastic-evictor TIMED_WAITING threads related to form data requests #26263
- No originalFilename in MockMultipartFile now leads to add it just as part #26261
- UriComponentsBuilder fromUriString cannot parse File URI #26258
📔 Documentation
- Slow prototype bean creation when migrating spring-boot 2.3.5 -> 2.4.1 #26369
- Application built against Spring Framework 5.3 breaks deployment to Wildfly 9 #26355
- Improve MockMvc samples in reference to show where static imports come from #26311
- MultipartFile.getOriginalFilename() documentation should warn user not to use it as destination file name #26299
- Spring data DomainClassConverter broken with Spring 5.3 in case of missing entity #26296
- Document initialization and shutdown logging semantics for the TestContext framework #25385
🔨 Dependency Upgrades
❤️ Contributors
We'd like to thank all the contributors who worked on this release!