Skip to content

Commit 0186809

Browse files
committed
Consistent catching of Throwable for introspection failures
Issue: SPR-12889
1 parent f6b8b84 commit 0186809

File tree

3 files changed

+39
-41
lines changed

3 files changed

+39
-41
lines changed

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

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public Annotation[] getDeclaredAnnotations() {
151151
*/
152152
public static Set<String> getMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
153153
Assert.notNull(element, "AnnotatedElement must not be null");
154-
Assert.notNull(annotationType, "annotationType must not be null");
154+
Assert.notNull(annotationType, "'annotationType' must not be null");
155155

156156
return getMetaAnnotationTypes(element, element.getAnnotation(annotationType));
157157
}
@@ -213,7 +213,7 @@ public Object process(AnnotatedElement annotatedElement, Annotation annotation,
213213
*/
214214
public static boolean hasMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
215215
Assert.notNull(element, "AnnotatedElement must not be null");
216-
Assert.notNull(annotationType, "annotationType must not be null");
216+
Assert.notNull(annotationType, "'annotationType' must not be null");
217217

218218
return hasMetaAnnotationTypes(element, annotationType, null);
219219
}
@@ -266,7 +266,7 @@ public Boolean process(AnnotatedElement annotatedElement, Annotation annotation,
266266
*/
267267
public static boolean isAnnotated(AnnotatedElement element, Class<? extends Annotation> annotationType) {
268268
Assert.notNull(element, "AnnotatedElement must not be null");
269-
Assert.notNull(annotationType, "annotationType must not be null");
269+
Assert.notNull(annotationType, "'annotationType' must not be null");
270270

271271
// Shortcut: directly present on the element, with no processing needed?
272272
if (element.isAnnotationPresent(annotationType)) {
@@ -315,7 +315,7 @@ public static boolean isAnnotated(AnnotatedElement element, String annotationNam
315315
public static AnnotationAttributes getMergedAnnotationAttributes(
316316
AnnotatedElement element, Class<? extends Annotation> annotationType) {
317317

318-
Assert.notNull(annotationType, "annotationType must not be null");
318+
Assert.notNull(annotationType, "'annotationType' must not be null");
319319
AnnotationAttributes attributes = searchWithGetSemantics(element, annotationType, null,
320320
new MergedAnnotationAttributesProcessor());
321321
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false);
@@ -399,7 +399,7 @@ public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElemen
399399
* @see AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)
400400
*/
401401
public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
402-
Assert.notNull(annotationType, "annotationType must not be null");
402+
Assert.notNull(annotationType, "'annotationType' must not be null");
403403

404404
// Shortcut: directly present on the element, with no merging needed?
405405
if (!(element instanceof Class)) {
@@ -440,7 +440,7 @@ public static <A extends Annotation> Set<A> getAllMergedAnnotations(AnnotatedEle
440440
Class<A> annotationType) {
441441

442442
Assert.notNull(element, "AnnotatedElement must not be null");
443-
Assert.notNull(annotationType, "annotationType must not be null");
443+
Assert.notNull(annotationType, "'annotationType' must not be null");
444444

445445
MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true);
446446
searchWithGetSemantics(element, annotationType, null, processor);
@@ -507,7 +507,7 @@ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(Annot
507507
Class<A> annotationType, Class<? extends Annotation> containerType) {
508508

509509
Assert.notNull(element, "AnnotatedElement must not be null");
510-
Assert.notNull(annotationType, "annotationType must not be null");
510+
Assert.notNull(annotationType, "'annotationType' must not be null");
511511

512512
if (containerType == null) {
513513
containerType = resolveContainerType(annotationType);
@@ -593,7 +593,7 @@ public Object process(AnnotatedElement annotatedElement, Annotation annotation,
593593
*/
594594
public static boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) {
595595
Assert.notNull(element, "AnnotatedElement must not be null");
596-
Assert.notNull(annotationType, "annotationType must not be null");
596+
Assert.notNull(annotationType, "'annotationType' must not be null");
597597

598598
// Shortcut: directly present on the element, with no processing needed?
599599
if (element.isAnnotationPresent(annotationType)) {
@@ -696,7 +696,7 @@ public static AnnotationAttributes findMergedAnnotationAttributes(AnnotatedEleme
696696
* @see #getMergedAnnotationAttributes(AnnotatedElement, Class)
697697
*/
698698
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
699-
Assert.notNull(annotationType, "annotationType must not be null");
699+
Assert.notNull(annotationType, "'annotationType' must not be null");
700700

701701
// Shortcut: directly present on the element, with no merging needed?
702702
if (!(element instanceof Class)) {
@@ -736,7 +736,7 @@ public static <A extends Annotation> Set<A> findAllMergedAnnotations(AnnotatedEl
736736
Class<A> annotationType) {
737737

738738
Assert.notNull(element, "AnnotatedElement must not be null");
739-
Assert.notNull(annotationType, "annotationType must not be null");
739+
Assert.notNull(annotationType, "'annotationType' must not be null");
740740

741741
MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true);
742742
searchWithFindSemantics(element, annotationType, null, processor);
@@ -803,7 +803,7 @@ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(Anno
803803
Class<A> annotationType, Class<? extends Annotation> containerType) {
804804

805805
Assert.notNull(element, "AnnotatedElement must not be null");
806-
Assert.notNull(annotationType, "annotationType must not be null");
806+
Assert.notNull(annotationType, "'annotationType' must not be null");
807807

808808
if (containerType == null) {
809809
containerType = resolveContainerType(annotationType);
@@ -910,7 +910,7 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
910910
}
911911
}
912912
}
913-
catch (Exception ex) {
913+
catch (Throwable ex) {
914914
AnnotationUtils.handleIntrospectionFailure(element, ex);
915915
}
916916
}
@@ -1199,7 +1199,7 @@ else if (element instanceof Class) {
11991199
}
12001200
}
12011201
}
1202-
catch (Exception ex) {
1202+
catch (Throwable ex) {
12031203
AnnotationUtils.handleIntrospectionFailure(element, ex);
12041204
}
12051205
}
@@ -1241,7 +1241,7 @@ private static <A extends Annotation> A[] getRawAnnotationsFromContainer(Annotat
12411241
try {
12421242
return (A[]) AnnotationUtils.getValue(container);
12431243
}
1244-
catch (Exception ex) {
1244+
catch (Throwable ex) {
12451245
AnnotationUtils.handleIntrospectionFailure(element, ex);
12461246
}
12471247
// Unable to read value from repeating annotation container -> ignore it.
@@ -1260,8 +1260,8 @@ private static Class<? extends Annotation> resolveContainerType(Class<? extends
12601260
Class<? extends Annotation> containerType = AnnotationUtils.resolveContainerAnnotationType(annotationType);
12611261
if (containerType == null) {
12621262
throw new IllegalArgumentException(
1263-
"annotationType must be a repeatable annotation: failed to resolve container type for "
1264-
+ annotationType.getName());
1263+
"Annotation type must be a repeatable annotation: failed to resolve container type for " +
1264+
annotationType.getName());
12651265
}
12661266
return containerType;
12671267
}
@@ -1283,15 +1283,15 @@ private static void validateContainerType(Class<? extends Annotation> annotation
12831283
Class<?> returnType = method.getReturnType();
12841284
if (!returnType.isArray() || returnType.getComponentType() != annotationType) {
12851285
String msg = String.format(
1286-
"Container type [%s] must declare a 'value' attribute for an array of type [%s]",
1287-
containerType.getName(), annotationType.getName());
1286+
"Container type [%s] must declare a 'value' attribute for an array of type [%s]",
1287+
containerType.getName(), annotationType.getName());
12881288
throw new AnnotationConfigurationException(msg);
12891289
}
12901290
}
1291-
catch (Exception ex) {
1291+
catch (Throwable ex) {
12921292
AnnotationUtils.rethrowAnnotationConfigurationException(ex);
12931293
String msg = String.format("Invalid declaration of container type [%s] for repeatable annotation [%s]",
1294-
containerType.getName(), annotationType.getName());
1294+
containerType.getName(), annotationType.getName());
12951295
throw new AnnotationConfigurationException(msg, ex);
12961296
}
12971297
}

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

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public static <A extends Annotation> A getAnnotation(Annotation ann, Class<A> an
158158
try {
159159
return synthesizeAnnotation(annotatedElement.getAnnotation(annotationType), annotatedElement);
160160
}
161-
catch (Exception ex) {
161+
catch (Throwable ex) {
162162
handleIntrospectionFailure(annotatedElement, ex);
163163
}
164164
return null;
@@ -189,7 +189,7 @@ public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedE
189189
}
190190
return synthesizeAnnotation(annotation, annotatedElement);
191191
}
192-
catch (Exception ex) {
192+
catch (Throwable ex) {
193193
handleIntrospectionFailure(annotatedElement, ex);
194194
}
195195
return null;
@@ -229,7 +229,7 @@ public static Annotation[] getAnnotations(AnnotatedElement annotatedElement) {
229229
try {
230230
return synthesizeAnnotationArray(annotatedElement.getAnnotations(), annotatedElement);
231231
}
232-
catch (Exception ex) {
232+
catch (Throwable ex) {
233233
handleIntrospectionFailure(annotatedElement, ex);
234234
}
235235
return null;
@@ -251,7 +251,7 @@ public static Annotation[] getAnnotations(Method method) {
251251
try {
252252
return synthesizeAnnotationArray(BridgeMethodResolver.findBridgedMethod(method).getAnnotations(), method);
253253
}
254-
catch (Exception ex) {
254+
catch (Throwable ex) {
255255
handleIntrospectionFailure(method, ex);
256256
}
257257
return null;
@@ -440,7 +440,7 @@ private static <A extends Annotation> Set<A> getRepeatableAnnotations(AnnotatedE
440440
}
441441
return new AnnotationCollector<>(annotationType, containerAnnotationType, declaredMode).getResult(annotatedElement);
442442
}
443-
catch (Exception ex) {
443+
catch (Throwable ex) {
444444
handleIntrospectionFailure(annotatedElement, ex);
445445
}
446446
return Collections.emptySet();
@@ -503,7 +503,7 @@ private static <A extends Annotation> A findAnnotation(
503503
}
504504
}
505505
}
506-
catch (Exception ex) {
506+
catch (Throwable ex) {
507507
handleIntrospectionFailure(annotatedElement, ex);
508508
}
509509
return null;
@@ -602,7 +602,7 @@ static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
602602
break;
603603
}
604604
}
605-
catch (Exception ex) {
605+
catch (Throwable ex) {
606606
handleIntrospectionFailure(ifcMethod, ex);
607607
}
608608
}
@@ -692,7 +692,7 @@ private static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A>
692692
}
693693
}
694694
}
695-
catch (Exception ex) {
695+
catch (Throwable ex) {
696696
handleIntrospectionFailure(clazz, ex);
697697
return null;
698698
}
@@ -809,7 +809,7 @@ public static boolean isAnnotationDeclaredLocally(Class<? extends Annotation> an
809809
}
810810
}
811811
}
812-
catch (Exception ex) {
812+
catch (Throwable ex) {
813813
handleIntrospectionFailure(clazz, ex);
814814
}
815815
return false;
@@ -872,12 +872,11 @@ public static boolean isAnnotationMetaPresent(Class<? extends Annotation> annota
872872
/**
873873
* Determine if the supplied {@link Annotation} is defined in the core JDK
874874
* {@code java.lang.annotation} package.
875-
* @param annotation the annotation to check (never {@code null})
875+
* @param annotation the annotation to check
876876
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
877877
*/
878878
public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
879-
Assert.notNull(annotation, "Annotation must not be null");
880-
return isInJavaLangAnnotationPackage(annotation.annotationType().getName());
879+
return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType().getName()));
881880
}
882881

883882
/**
@@ -888,8 +887,7 @@ public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
888887
* @since 4.2
889888
*/
890889
public static boolean isInJavaLangAnnotationPackage(String annotationType) {
891-
Assert.hasText(annotationType, "annotationType must not be null or empty");
892-
return annotationType.startsWith("java.lang.annotation");
890+
return (annotationType != null && annotationType.startsWith("java.lang.annotation"));
893891
}
894892

895893
/**
@@ -1046,7 +1044,7 @@ static AnnotationAttributes retrieveAnnotationAttributes(Object annotatedElement
10461044
attributes.put(method.getName(),
10471045
adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
10481046
}
1049-
catch (Exception ex) {
1047+
catch (Throwable ex) {
10501048
if (ex instanceof InvocationTargetException) {
10511049
Throwable targetException = ((InvocationTargetException) ex).getTargetException();
10521050
rethrowAnnotationConfigurationException(targetException);
@@ -1461,7 +1459,7 @@ static <A extends Annotation> A synthesizeAnnotation(A annotation, Object annota
14611459
public static <A extends Annotation> A synthesizeAnnotation(Map<String, Object> attributes,
14621460
Class<A> annotationType, AnnotatedElement annotatedElement) {
14631461

1464-
Assert.notNull(annotationType, "annotationType must not be null");
1462+
Assert.notNull(annotationType, "'annotationType' must not be null");
14651463
if (attributes == null) {
14661464
return null;
14671465
}
@@ -1541,7 +1539,7 @@ static Annotation[] synthesizeAnnotationArray(Annotation[] annotations, Object a
15411539
*/
15421540
@SuppressWarnings("unchecked")
15431541
static <A extends Annotation> A[] synthesizeAnnotationArray(Map<String, Object>[] maps, Class<A> annotationType) {
1544-
Assert.notNull(annotationType, "annotationType must not be null");
1542+
Assert.notNull(annotationType, "'annotationType' must not be null");
15451543
if (maps == null) {
15461544
return null;
15471545
}
@@ -1809,7 +1807,7 @@ static void rethrowAnnotationConfigurationException(Throwable ex) {
18091807
* @param ex the exception that we encountered
18101808
* @see #rethrowAnnotationConfigurationException
18111809
*/
1812-
static void handleIntrospectionFailure(AnnotatedElement element, Exception ex) {
1810+
static void handleIntrospectionFailure(AnnotatedElement element, Throwable ex) {
18131811
rethrowAnnotationConfigurationException(ex);
18141812

18151813
Log loggerToUse = logger;
@@ -1921,7 +1919,7 @@ else if (!isInJavaLangAnnotationPackage(ann)) {
19211919
}
19221920
}
19231921
}
1924-
catch (Exception ex) {
1922+
catch (Throwable ex) {
19251923
handleIntrospectionFailure(element, ex);
19261924
}
19271925
}
@@ -1936,7 +1934,7 @@ private List<A> getValue(AnnotatedElement element, Annotation annotation) {
19361934
}
19371935
return synthesizedAnnotations;
19381936
}
1939-
catch (Exception ex) {
1937+
catch (Throwable ex) {
19401938
handleIntrospectionFailure(element, ex);
19411939
}
19421940
// Unable to read value from repeating annotation container -> ignore it.

spring-core/src/test/java/org/springframework/core/annotation/ComposedRepeatableAnnotationsTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public void findComposedContainerForRepeatableAnnotationsOnClass() {
186186

187187
private void expectNonRepeatableAnnotation() {
188188
exception.expect(IllegalArgumentException.class);
189-
exception.expectMessage(startsWith("annotationType must be a repeatable annotation"));
189+
exception.expectMessage(startsWith("Annotation type must be a repeatable annotation"));
190190
exception.expectMessage(containsString("failed to resolve container type for"));
191191
exception.expectMessage(containsString(NonRepeatable.class.getName()));
192192
}

0 commit comments

Comments
 (0)