From 0150c4ba06d6b4e388f19e98e947a1aecb117c55 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 8 Apr 2026 13:39:10 +0200 Subject: [PATCH 1/4] Avoid MessageFormat rendering for exception messages in binding errors Closes gh-36609 --- .../DefaultBindingErrorProcessor.java | 42 +++++++++++++++---- .../validation/DataBinderTests.java | 4 ++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java b/spring-context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java index 47aa53f0465..dd1b3e18695 100644 --- a/spring-context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java +++ b/spring-context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java @@ -16,6 +16,10 @@ package org.springframework.validation; +import java.io.Serializable; + +import org.jspecify.annotations.Nullable; + import org.springframework.beans.PropertyAccessException; import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.util.Assert; @@ -59,9 +63,8 @@ public class DefaultBindingErrorProcessor implements BindingErrorProcessor { String fixedField = bindingResult.getNestedPath() + missingField; String[] codes = bindingResult.resolveMessageCodes(MISSING_FIELD_ERROR_CODE, missingField); Object[] arguments = getArgumentsForBindError(bindingResult.getObjectName(), fixedField); - FieldError error = new FieldError(bindingResult.getObjectName(), fixedField, "", true, - codes, arguments, "Field '" + fixedField + "' is required"); - bindingResult.addError(error); + bindingResult.addError(new BindingFieldError( + bindingResult.getObjectName(), fixedField, "", codes, arguments)); } @Override @@ -75,10 +78,8 @@ public class DefaultBindingErrorProcessor implements BindingErrorProcessor { if (ObjectUtils.isArray(rejectedValue)) { rejectedValue = StringUtils.arrayToCommaDelimitedString(ObjectUtils.toObjectArray(rejectedValue)); } - FieldError error = new FieldError(bindingResult.getObjectName(), field, rejectedValue, true, - codes, arguments, ex.getLocalizedMessage()); - error.wrap(ex); - bindingResult.addError(error); + bindingResult.addError(new BindingFieldError( + bindingResult.getObjectName(), field, rejectedValue, codes, arguments, ex)); } /** @@ -97,4 +98,31 @@ public class DefaultBindingErrorProcessor implements BindingErrorProcessor { return new Object[] {new DefaultMessageSourceResolvable(codes, field)}; } + + /** + * Subclass of {@code FieldError} with Spring-style default message rendering. + */ + @SuppressWarnings("serial") + private static class BindingFieldError extends FieldError implements Serializable { + + public BindingFieldError(String objectName, String field, @Nullable Object rejectedValue, String[] codes, + Object[] arguments) { + + super(objectName, field, rejectedValue, true, codes, arguments, + "Field '" + field + "' is required"); + } + + public BindingFieldError(String objectName, String field, @Nullable Object rejectedValue, String[] codes, + Object[] arguments, PropertyAccessException ex) { + + super(objectName, field, rejectedValue, true, codes, arguments, ex.getLocalizedMessage()); + wrap(ex); + } + + @Override + public boolean shouldRenderDefaultMessage() { + return false; + } + } + } diff --git a/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java b/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java index 92a9e18a99d..54160ad3e6f 100644 --- a/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java +++ b/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java @@ -1854,8 +1854,12 @@ class DataBinderTests { FieldError ageError = errors.getFieldError("age"); assertThat(ageError.getCode()).isEqualTo("typeMismatch"); + assertThat(ageError.isBindingFailure()).isTrue(); + assertThat(ageError.shouldRenderDefaultMessage()).isFalse(); FieldError nameError = errors.getFieldError("name"); assertThat(nameError.getCode()).isEqualTo("badName"); + assertThat(nameError.isBindingFailure()).isFalse(); + assertThat(nameError.shouldRenderDefaultMessage()).isTrue(); } @Test From b8f1005897cb540dcee8bef4619e6117c5cb5f81 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 8 Apr 2026 13:39:20 +0200 Subject: [PATCH 2/4] Improve SpringValidatorAdapter and MethodValidationAdapter performance Closes gh-36621 --- .../MethodValidationAdapter.java | 7 +++- .../SpringValidatorAdapter.java | 32 +++++++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java index 63e57687bc9..479f4360847 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java @@ -533,7 +533,7 @@ public class MethodValidationAdapter implements MethodValidator { @SuppressWarnings("serial") - private static class ViolationMessageSourceResolvable extends DefaultMessageSourceResolvable { + private class ViolationMessageSourceResolvable extends DefaultMessageSourceResolvable { private final transient ConstraintViolation violation; @@ -547,6 +547,11 @@ public class MethodValidationAdapter implements MethodValidator { public ConstraintViolation getViolation() { return this.violation; } + + @Override + public boolean shouldRenderDefaultMessage() { + return validatorAdapter.get().requiresMessageFormat(this.violation); + } } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index 04b0247a5b5..78348e3c194 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -18,6 +18,7 @@ package org.springframework.validation.beanvalidation; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -64,7 +65,7 @@ import org.springframework.validation.SmartValidator; */ public class SpringValidatorAdapter implements SmartValidator, jakarta.validation.Validator { - private static final Set internalAnnotationAttributes = Set.of("message", "groups", "payload"); + private static final Set INTERNAL_ANNOTATION_ATTRIBUTES = Set.of("message", "groups", "payload"); private jakarta.validation.@Nullable Validator targetValidator; @@ -144,10 +145,21 @@ public class SpringValidatorAdapter implements SmartValidator, jakarta.validatio */ @SuppressWarnings("serial") protected void processConstraintViolations(Set> violations, Errors errors) { + // Pre-identify binding failures (using getAllErrors to avoid intermediate list) + Set failedFields = new HashSet<>(); + if (errors.hasErrors()) { + for (ObjectError error : errors.getAllErrors()) { + if (error instanceof FieldError fieldError && fieldError.isBindingFailure()) { + failedFields.add(fieldError.getField()); + } + } + } + + // Turn the ConstraintViolations into Object/FieldErrors, + // but only for fields where binding has been successful. for (ConstraintViolation violation : violations) { String field = determineField(violation); - FieldError fieldError = errors.getFieldError(field); - if (fieldError == null || !fieldError.isBindingFailure()) { + if (!failedFields.contains(field)) { try { ConstraintDescriptor cd = violation.getConstraintDescriptor(); String errorCode = determineErrorCode(cd); @@ -158,14 +170,14 @@ public class SpringValidatorAdapter implements SmartValidator, jakarta.validatio String nestedField = bindingResult.getNestedPath() + field; if (nestedField.isEmpty()) { String[] errorCodes = bindingResult.resolveMessageCodes(errorCode); - ObjectError error = new ViolationObjectError( + ObjectError error = new ValidationObjectError( errors.getObjectName(), errorCodes, errorArgs, violation, this); bindingResult.addError(error); } else { Object rejectedValue = getRejectedValue(field, violation, bindingResult); String[] errorCodes = bindingResult.resolveMessageCodes(errorCode, field); - FieldError error = new ViolationFieldError(errors.getObjectName(), nestedField, + FieldError error = new ValidationFieldError(errors.getObjectName(), nestedField, rejectedValue, errorCodes, errorArgs, violation, this); bindingResult.addError(error); } @@ -260,7 +272,7 @@ public class SpringValidatorAdapter implements SmartValidator, jakarta.validatio // Using a TreeMap for alphabetical ordering of attribute names Map attributesToExpose = new TreeMap<>(); descriptor.getAttributes().forEach((attributeName, attributeValue) -> { - if (!internalAnnotationAttributes.contains(attributeName)) { + if (!INTERNAL_ANNOTATION_ATTRIBUTES.contains(attributeName)) { if (attributeValue instanceof String str) { attributeValue = new ResolvableAttribute(str); } @@ -439,13 +451,13 @@ public class SpringValidatorAdapter implements SmartValidator, jakarta.validatio * Subclass of {@code ObjectError} with Spring-style default message rendering. */ @SuppressWarnings("serial") - private static class ViolationObjectError extends ObjectError implements Serializable { + private static class ValidationObjectError extends ObjectError implements Serializable { private @Nullable transient SpringValidatorAdapter adapter; private @Nullable transient ConstraintViolation violation; - public ViolationObjectError(String objectName, String[] codes, Object[] arguments, + public ValidationObjectError(String objectName, String[] codes, Object[] arguments, ConstraintViolation violation, SpringValidatorAdapter adapter) { super(objectName, codes, arguments, violation.getMessage()); @@ -467,13 +479,13 @@ public class SpringValidatorAdapter implements SmartValidator, jakarta.validatio * Subclass of {@code FieldError} with Spring-style default message rendering. */ @SuppressWarnings("serial") - private static class ViolationFieldError extends FieldError implements Serializable { + private static class ValidationFieldError extends FieldError implements Serializable { private @Nullable transient SpringValidatorAdapter adapter; private @Nullable transient ConstraintViolation violation; - public ViolationFieldError(String objectName, String field, @Nullable Object rejectedValue, String[] codes, + public ValidationFieldError(String objectName, String field, @Nullable Object rejectedValue, String[] codes, Object[] arguments, ConstraintViolation violation, SpringValidatorAdapter adapter) { super(objectName, field, rejectedValue, false, codes, arguments, violation.getMessage()); From 1687d90a8cbf9af530ce75d4a06abf128844e9ab Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 8 Apr 2026 13:41:32 +0200 Subject: [PATCH 3/4] Polishing --- .../util/ConcurrentLruCache.java | 14 +++++-- .../springframework/web/ErrorResponse.java | 8 ++-- .../web/bind/WebDataBinder.java | 4 +- .../web/method/HandlerMethod.java | 16 ++++---- .../resource/ResourceHttpRequestHandler.java | 39 +++++++++++-------- 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java b/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java index f5506f387db..ee11b0ca8f7 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java @@ -32,9 +32,11 @@ import org.jspecify.annotations.Nullable; /** * Simple LRU (Least Recently Used) cache, bounded by a specified cache capacity. + * *

This is a simplified, opinionated implementation of an LRU cache for internal * use in Spring Framework. It is inspired from * ConcurrentLinkedHashMap. + * *

Read and write operations are internally recorded in dedicated buffers, * then drained at chosen times to avoid contention. * @@ -70,6 +72,7 @@ public final class ConcurrentLruCache { private final AtomicReference drainStatus = new AtomicReference<>(DrainStatus.IDLE); + /** * Create a new cache instance with the given capacity and generator function. * @param capacity the maximum number of entries in the cache @@ -89,6 +92,7 @@ public final class ConcurrentLruCache { this.writeOperations = new WriteOperations(); } + /** * Retrieve an entry from the cache, potentially triggering generation of the value. * @param key the key to retrieve the entry for @@ -344,10 +348,13 @@ public final class ConcurrentLruCache { abstract boolean shouldDrainBuffers(boolean delayable); } + private enum CacheEntryState { + ACTIVE, PENDING_REMOVAL, REMOVED } + private record CacheEntry(V value, CacheEntryState state) { boolean isActive() { @@ -355,6 +362,7 @@ public final class ConcurrentLruCache { } } + private static final class ReadOperations { private static final int BUFFER_COUNT = detectNumberOfBuffers(); @@ -452,6 +460,7 @@ public final class ConcurrentLruCache { } } + private static final class WriteOperations { private static final int DRAIN_THRESHOLD = 16; @@ -478,11 +487,12 @@ public final class ConcurrentLruCache { task.run(); } } - } + @SuppressWarnings("serial") private static final class Node extends AtomicReference> { + final K key; @Nullable Node prev; @@ -522,7 +532,6 @@ public final class ConcurrentLruCache { @Nullable Node last; - @Nullable Node poll() { if (this.first == null) { return null; @@ -596,7 +605,6 @@ public final class ConcurrentLruCache { unlink(e); } } - } } diff --git a/spring-web/src/main/java/org/springframework/web/ErrorResponse.java b/spring-web/src/main/java/org/springframework/web/ErrorResponse.java index 6da004fe746..4908762524a 100644 --- a/spring-web/src/main/java/org/springframework/web/ErrorResponse.java +++ b/spring-web/src/main/java/org/springframework/web/ErrorResponse.java @@ -29,15 +29,15 @@ import org.springframework.http.ProblemDetail; /** * Representation of a complete RFC 9457 error response including status, - * headers, and an RFC 9457 formatted {@link ProblemDetail} body. Allows any - * exception to expose HTTP error response information. + * headers, and an RFC 9457 formatted {@link ProblemDetail} body. + * Allows any exception to expose HTTP error response information. * *

{@link ErrorResponseException} is a default implementation of this * interface and a convenient base class for other exceptions to use. * *

{@code ErrorResponse} is supported as a return value from - * {@code @ExceptionHandler} methods that render directly to the response, for example, - * by being marked {@code @ResponseBody}, or declared in an + * {@code @ExceptionHandler} methods that render directly to the response, + * for example, by being marked {@code @ResponseBody}, or declared in an * {@code @RestController} or {@code RestControllerAdvice} class. * * @author Rossen Stoyanchev diff --git a/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java index d659aad4f46..7f1710cfe87 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java @@ -200,7 +200,9 @@ public class WebDataBinder extends DataBinder { * @return the resolved value, or {@code null} * @since 6.1 */ - protected @Nullable Object resolvePrefixValue(String name, Class type, BiFunction, Object> resolver) { + protected @Nullable Object resolvePrefixValue( + String name, Class type, BiFunction, @Nullable Object> resolver) { + Object value = resolver.apply(name, type); if (value == null) { String prefix = getFieldDefaultPrefix(); diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 6e098307ad8..7114c2a300b 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -96,7 +96,7 @@ public class HandlerMethod extends AnnotatedMethod { private @Nullable HandlerMethod resolvedFromHandlerMethod; - private @Nullable HandlerMethod resolvedBeanHandlerMethod; + private volatile @Nullable HandlerMethod resolvedBeanHandlerMethod; private final String description; @@ -233,7 +233,10 @@ public class HandlerMethod extends AnnotatedMethod { this.responseStatus = annotation.code(); this.responseStatusReason = resolvedReason; if (StringUtils.hasText(this.responseStatusReason) && getMethod().getReturnType() != void.class) { - logger.warn("Return value of [" + getMethod() + "] will be ignored since @ResponseStatus 'reason' attribute is set."); + if (logger.isWarnEnabled()) { + logger.warn("Return value of [" + getMethod() + + "] will be ignored since @ResponseStatus 'reason' attribute is set."); + } } } } @@ -352,23 +355,22 @@ public class HandlerMethod extends AnnotatedMethod { *

If the {@link #getBean() handler} is not String, return the same instance. */ public HandlerMethod createWithResolvedBean() { - if (this.resolvedBeanHandlerMethod != null) { - return this.resolvedBeanHandlerMethod; + HandlerMethod resolvedBeanHandlerMethod = this.resolvedBeanHandlerMethod; + if (resolvedBeanHandlerMethod != null) { + return resolvedBeanHandlerMethod; } + // We need to resolve a bean name reference. if (!(this.bean instanceof String beanName)) { return this; } - Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory"); Object handler = this.beanFactory.getBean(beanName); - Assert.notNull(handler, "No handler instance"); HandlerMethod handlerMethod = new HandlerMethod(this, handler, false); if (this.beanFactory.isSingleton(beanName)) { this.resolvedBeanHandlerMethod = handlerMethod; } - return handlerMethod; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 8949b91d413..72e04b077d7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -199,7 +199,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator /** * Configure the list of {@link ResourceResolver ResourceResolvers} to use. - *

By default {@link PathResourceResolver} is configured. If using this property, + *

By default, {@link PathResourceResolver} is configured. If using this property, * it is recommended to add {@link PathResourceResolver} as the last resolver. */ public void setResourceResolvers(@Nullable List resourceResolvers) { @@ -218,7 +218,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator /** * Configure the list of {@link ResourceTransformer ResourceTransformers} to use. - *

By default no transformers are configured for use. + *

By default, no transformers are configured for use. */ public void setResourceTransformers(@Nullable List resourceTransformers) { this.resourceTransformers.clear(); @@ -236,7 +236,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator /** * Configure the {@link ResourceHttpMessageConverter} to use. - *

By default a {@link ResourceHttpMessageConverter} will be configured. + *

By default, a {@link ResourceHttpMessageConverter} will be configured. * @since 4.3 */ public void setResourceHttpMessageConverter(@Nullable ResourceHttpMessageConverter messageConverter) { @@ -253,7 +253,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator /** * Configure the {@link ResourceRegionHttpMessageConverter} to use. - *

By default a {@link ResourceRegionHttpMessageConverter} will be configured. + *

By default, a {@link ResourceRegionHttpMessageConverter} will be configured. * @since 4.3 */ public void setResourceRegionHttpMessageConverter(@Nullable ResourceRegionHttpMessageConverter messageConverter) { @@ -294,7 +294,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator /** * Specify the CORS configuration for resources served by this handler. - *

By default this is not set in which allows cross-origin requests. + *

By default, this is not set in which allows cross-origin requests. */ public void setCorsConfiguration(CorsConfiguration corsConfiguration) { this.corsConfiguration = corsConfiguration; @@ -523,7 +523,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator // For very general mappings (for example, "/") we need to check 404 first Resource resource = getResource(request); if (resource == null) { - logger.debug("Resource not found"); throw new NoResourceFoundException(HttpMethod.valueOf(request.getMethod()), request.getRequestURI(), getPath(request)); } @@ -539,10 +538,12 @@ public class ResourceHttpRequestHandler extends WebContentGenerator prepareResponse(response); // Header phase - String eTagValue = (getEtagGenerator() != null ? getEtagGenerator().apply(resource) : null); + String etagValue = (getEtagGenerator() != null ? getEtagGenerator().apply(resource) : null); long lastModified = (isUseLastModified() ? resource.lastModified() : -1); - if (new ServletWebRequest(request, response).checkNotModified(eTagValue, lastModified)) { - logger.trace("Resource not modified"); + if (new ServletWebRequest(request, response).checkNotModified(etagValue, lastModified)) { + if (logger.isTraceEnabled()) { + logger.trace("Resource not modified: " + resource); + } return; } @@ -553,8 +554,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator // Content phase ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response); if (request.getHeader(HttpHeaders.RANGE) == null) { - Assert.state(this.resourceHttpMessageConverter != null, "Not initialized"); - + Assert.state(this.resourceHttpMessageConverter != null, "Converter not initialized"); if (HttpMethod.HEAD.matches(request.getMethod())) { this.resourceHttpMessageConverter.addDefaultHeaders(outputMessage, resource, mediaType); outputMessage.flush(); @@ -564,7 +564,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator } } else { - Assert.state(this.resourceRegionHttpMessageConverter != null, "Not initialized"); + Assert.state(this.resourceRegionHttpMessageConverter != null, "Converter not initialized"); ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(request); try { List httpRanges = inputMessage.getHeaders().getRange(); @@ -584,14 +584,21 @@ public class ResourceHttpRequestHandler extends WebContentGenerator String path = getPath(request); path = processPath(path); if (ResourceHandlerUtils.shouldIgnoreInputPath(path) || isInvalidPath(path)) { + if (logger.isDebugEnabled()) { + logger.debug("Ignoring invalid resource path [" + path + "]"); + } return null; } - Assert.state(this.resolverChain != null, "ResourceResolverChain not initialized."); - Assert.state(this.transformerChain != null, "ResourceTransformerChain not initialized."); - + Assert.state(this.resolverChain != null, "ResourceResolverChain not initialized"); + Assert.state(this.transformerChain != null, "ResourceTransformerChain not initialized"); Resource resource = this.resolverChain.resolveResource(request, path, getLocations()); - if (resource != null) { + if (resource == null) { + if (logger.isDebugEnabled()) { + logger.debug("Resource not found for path [" + path + "]"); + } + } + else { resource = this.transformerChain.transform(request, resource); } return resource; From d7ddfe8d2ef6827dda31123e50bdb916873b8c40 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 8 Apr 2026 13:41:57 +0200 Subject: [PATCH 4/4] Upgrade to Log4J 2.25.4, Groovy 5.0.5, Hibernate ORM 7.2.10, Mockito 5.23, Checkstyle 13.4 --- .../org/springframework/build/CheckstyleConventions.java | 2 +- framework-platform/framework-platform.gradle | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java b/buildSrc/src/main/java/org/springframework/build/CheckstyleConventions.java index acc31de778b..be724315a1a 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("13.3.0"); + checkstyle.setToolVersion("13.4.0"); 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 cd5e77f6c56..80cdf050a02 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -12,15 +12,15 @@ dependencies { api(platform("io.netty:netty-bom:4.2.12.Final")) api(platform("io.projectreactor:reactor-bom:2025.0.4")) api(platform("io.rsocket:rsocket-bom:1.1.5")) - api(platform("org.apache.groovy:groovy-bom:5.0.4")) - api(platform("org.apache.logging.log4j:log4j-bom:2.25.3")) + api(platform("org.apache.groovy:groovy-bom:5.0.5")) + api(platform("org.apache.logging.log4j:log4j-bom:2.25.4")) api(platform("org.assertj:assertj-bom:3.27.7")) api(platform("org.eclipse.jetty:jetty-bom:12.1.7")) api(platform("org.eclipse.jetty.ee11:jetty-ee11-bom:12.1.7")) api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2")) api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.9.0")) api(platform("org.junit:junit-bom:6.0.3")) - api(platform("org.mockito:mockito-bom:5.22.0")) + api(platform("org.mockito:mockito-bom:5.23.0")) api(platform("tools.jackson:jackson-bom:3.0.4")) constraints { @@ -120,7 +120,7 @@ dependencies { api("org.glassfish:jakarta.el:4.0.2") api("org.graalvm.sdk:graal-sdk:22.3.1") api("org.hamcrest:hamcrest:3.0") - api("org.hibernate.orm:hibernate-core:7.2.7.Final") + api("org.hibernate.orm:hibernate-core:7.2.10.Final") api("org.hibernate.validator:hibernate-validator:9.1.0.Final") api("org.hsqldb:hsqldb:2.7.4") api("org.htmlunit:htmlunit:4.21.0")