Skip to content

Commit 4d44aaf

Browse files
committed
Omit deprecation warning for Bean Validation constraint annotations
Prior to this commit, AnnotationTypeMapping logged a warning for the use of convention-based annotation attribute overrides in composed Bean Validation constraint annotations, even though those attribute overrides are not related to Spring. For example, Hibernate's @url constraint annotation is meta-annotated with Bean Validation's @pattern constraint annotation, and we should not log a warning in such scenarios. This commit addresses that by not logging a warning if convention-based annotation attribute overrides are detected for a composed @constraint annotation. Closes gh-29206
1 parent 0e861af commit 4d44aaf

File tree

2 files changed

+73
-5
lines changed

2 files changed

+73
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2002-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.validation.beanvalidation;
18+
19+
import java.lang.reflect.Method;
20+
21+
import org.hibernate.validator.constraints.URL;
22+
import org.junit.jupiter.api.Disabled;
23+
import org.junit.jupiter.api.Test;
24+
25+
import org.springframework.core.annotation.MergedAnnotations;
26+
27+
/**
28+
* Smoke tests specific to the combination of {@link MergedAnnotations}
29+
* and Bean Validation constraint annotations.
30+
*
31+
* @author Sam Brannen
32+
* @since 6.0
33+
*/
34+
class BeanValidationMergedAnnotationsTests {
35+
36+
@Disabled("This test should only be run manually to inspect log messages")
37+
@Test
38+
@URL
39+
void constraintAnnotationOnMethod() throws Exception {
40+
// If the issue raised in gh-29206 had not been addressed, we would see
41+
// a log message similar to the following.
42+
// 19:07:33.848 [main] WARN o.s.c.a.AnnotationTypeMapping - Support for
43+
// convention-based annotation attribute overrides is deprecated and will
44+
// be removed in Spring Framework 6.1. Please annotate the following attributes
45+
// in @org.hibernate.validator.constraints.URL with appropriate @AliasFor
46+
// declarations: [regexp, payload, flags, groups, message]
47+
Method method = getClass().getDeclaredMethod("constraintAnnotationOnMethod");
48+
MergedAnnotations mergedAnnotations = MergedAnnotations.from(method);
49+
mergedAnnotations.get(URL.class);
50+
}
51+
52+
}

spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Map;
3030
import java.util.Set;
3131
import java.util.concurrent.ConcurrentHashMap;
32+
import java.util.function.Predicate;
3233

3334
import org.apache.commons.logging.Log;
3435
import org.apache.commons.logging.LogFactory;
@@ -52,9 +53,15 @@ final class AnnotationTypeMapping {
5253

5354
private static final Log logger = LogFactory.getLog(AnnotationTypeMapping.class);
5455

56+
private static final Predicate<? super Annotation> isBeanValidationConstraint = annotation ->
57+
annotation.annotationType().getName().equals("jakarta.validation.Constraint");
58+
5559
/**
56-
* Set of fully qualified class names for annotations which we have already
57-
* checked for use of convention-based annotation attribute overrides.
60+
* Set used to track which convention-based annotation attribute overrides
61+
* have already been checked. Each key is the combination of the fully
62+
* qualified class names of a composed annotation and a meta-annotation
63+
* that it is either present or meta-present on the composed annotation,
64+
* separated by a dash.
5865
* @since 6.0
5966
* @see #addConventionMappings()
6067
*/
@@ -299,9 +306,18 @@ private void addConventionMappings() {
299306
}
300307
}
301308
String rootAnnotationTypeName = this.root.annotationType.getName();
302-
// We want to avoid duplicate log warnings as much as possible, without full synchronization.
303-
if (conventionBasedOverrideCheckCache.add(rootAnnotationTypeName) &&
304-
!conventionMappedAttributes.isEmpty() && logger.isWarnEnabled()) {
309+
String cacheKey = rootAnnotationTypeName + '-' + this.annotationType.getName();
310+
// We want to avoid duplicate log warnings as much as possible, without full synchronization,
311+
// and we intentionally invoke add() before checking if any convention-based overrides were
312+
// actually encountered in order to ensure that we add a "tracked" entry for the current cache
313+
// key in any case.
314+
// In addition, we do NOT want to log warnings for custom Java Bean Validation constraint
315+
// annotations that are meta-annotated with other constraint annotations -- for example,
316+
// @org.hibernate.validator.constraints.URL which overrides attributes in
317+
// @jakarta.validation.constraints.Pattern.
318+
if (conventionBasedOverrideCheckCache.add(cacheKey) && !conventionMappedAttributes.isEmpty() &&
319+
Arrays.stream(this.annotationType.getAnnotations()).noneMatch(isBeanValidationConstraint) &&
320+
logger.isWarnEnabled()) {
305321
logger.warn("""
306322
Support for convention-based annotation attribute overrides is deprecated \
307323
and will be removed in Spring Framework 6.1. Please annotate the following \

0 commit comments

Comments
 (0)