Skip to content

Commit 17f7f1f

Browse files
committed
Consistent catching of Throwable for introspection failures
Issue: SPR-12889 (cherry picked from commit 0186809)
1 parent cbc512f commit 17f7f1f

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)) {
@@ -333,7 +333,7 @@ public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement elem
333333
public static AnnotationAttributes getMergedAnnotationAttributes(
334334
AnnotatedElement element, Class<? extends Annotation> annotationType) {
335335

336-
Assert.notNull(annotationType, "annotationType must not be null");
336+
Assert.notNull(annotationType, "'annotationType' must not be null");
337337
AnnotationAttributes attributes = searchWithGetSemantics(element, annotationType, null,
338338
new MergedAnnotationAttributesProcessor());
339339
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false);
@@ -417,7 +417,7 @@ public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElemen
417417
* @see AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)
418418
*/
419419
public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
420-
Assert.notNull(annotationType, "annotationType must not be null");
420+
Assert.notNull(annotationType, "'annotationType' must not be null");
421421

422422
// Shortcut: directly present on the element, with no merging needed?
423423
if (!(element instanceof Class)) {
@@ -458,7 +458,7 @@ public static <A extends Annotation> Set<A> getAllMergedAnnotations(AnnotatedEle
458458
Class<A> annotationType) {
459459

460460
Assert.notNull(element, "AnnotatedElement must not be null");
461-
Assert.notNull(annotationType, "annotationType must not be null");
461+
Assert.notNull(annotationType, "'annotationType' must not be null");
462462

463463
MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true);
464464
searchWithGetSemantics(element, annotationType, null, processor);
@@ -525,7 +525,7 @@ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(Annot
525525
Class<A> annotationType, Class<? extends Annotation> containerType) {
526526

527527
Assert.notNull(element, "AnnotatedElement must not be null");
528-
Assert.notNull(annotationType, "annotationType must not be null");
528+
Assert.notNull(annotationType, "'annotationType' must not be null");
529529

530530
if (containerType == null) {
531531
containerType = resolveContainerType(annotationType);
@@ -611,7 +611,7 @@ public Object process(AnnotatedElement annotatedElement, Annotation annotation,
611611
*/
612612
public static boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) {
613613
Assert.notNull(element, "AnnotatedElement must not be null");
614-
Assert.notNull(annotationType, "annotationType must not be null");
614+
Assert.notNull(annotationType, "'annotationType' must not be null");
615615

616616
// Shortcut: directly present on the element, with no processing needed?
617617
if (element.isAnnotationPresent(annotationType)) {
@@ -714,7 +714,7 @@ public static AnnotationAttributes findMergedAnnotationAttributes(AnnotatedEleme
714714
* @see #getMergedAnnotationAttributes(AnnotatedElement, Class)
715715
*/
716716
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
717-
Assert.notNull(annotationType, "annotationType must not be null");
717+
Assert.notNull(annotationType, "'annotationType' must not be null");
718718

719719
// Shortcut: directly present on the element, with no merging needed?
720720
if (!(element instanceof Class)) {
@@ -783,7 +783,7 @@ public static <A extends Annotation> Set<A> findAllMergedAnnotations(AnnotatedEl
783783
Class<A> annotationType) {
784784

785785
Assert.notNull(element, "AnnotatedElement must not be null");
786-
Assert.notNull(annotationType, "annotationType must not be null");
786+
Assert.notNull(annotationType, "'annotationType' must not be null");
787787

788788
MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true);
789789
searchWithFindSemantics(element, annotationType, null, processor);
@@ -850,7 +850,7 @@ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(Anno
850850
Class<A> annotationType, Class<? extends Annotation> containerType) {
851851

852852
Assert.notNull(element, "AnnotatedElement must not be null");
853-
Assert.notNull(annotationType, "annotationType must not be null");
853+
Assert.notNull(annotationType, "'annotationType' must not be null");
854854

855855
if (containerType == null) {
856856
containerType = resolveContainerType(annotationType);
@@ -957,7 +957,7 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
957957
}
958958
}
959959
}
960-
catch (Exception ex) {
960+
catch (Throwable ex) {
961961
AnnotationUtils.handleIntrospectionFailure(element, ex);
962962
}
963963
}
@@ -1246,7 +1246,7 @@ else if (element instanceof Class) {
12461246
}
12471247
}
12481248
}
1249-
catch (Exception ex) {
1249+
catch (Throwable ex) {
12501250
AnnotationUtils.handleIntrospectionFailure(element, ex);
12511251
}
12521252
}
@@ -1288,7 +1288,7 @@ private static <A extends Annotation> A[] getRawAnnotationsFromContainer(Annotat
12881288
try {
12891289
return (A[]) AnnotationUtils.getValue(container);
12901290
}
1291-
catch (Exception ex) {
1291+
catch (Throwable ex) {
12921292
AnnotationUtils.handleIntrospectionFailure(element, ex);
12931293
}
12941294
// Unable to read value from repeating annotation container -> ignore it.
@@ -1307,8 +1307,8 @@ private static Class<? extends Annotation> resolveContainerType(Class<? extends
13071307
Class<? extends Annotation> containerType = AnnotationUtils.resolveContainerAnnotationType(annotationType);
13081308
if (containerType == null) {
13091309
throw new IllegalArgumentException(
1310-
"annotationType must be a repeatable annotation: failed to resolve container type for "
1311-
+ annotationType.getName());
1310+
"Annotation type must be a repeatable annotation: failed to resolve container type for " +
1311+
annotationType.getName());
13121312
}
13131313
return containerType;
13141314
}
@@ -1330,15 +1330,15 @@ private static void validateContainerType(Class<? extends Annotation> annotation
13301330
Class<?> returnType = method.getReturnType();
13311331
if (!returnType.isArray() || returnType.getComponentType() != annotationType) {
13321332
String msg = String.format(
1333-
"Container type [%s] must declare a 'value' attribute for an array of type [%s]",
1334-
containerType.getName(), annotationType.getName());
1333+
"Container type [%s] must declare a 'value' attribute for an array of type [%s]",
1334+
containerType.getName(), annotationType.getName());
13351335
throw new AnnotationConfigurationException(msg);
13361336
}
13371337
}
1338-
catch (Exception ex) {
1338+
catch (Throwable ex) {
13391339
AnnotationUtils.rethrowAnnotationConfigurationException(ex);
13401340
String msg = String.format("Invalid declaration of container type [%s] for repeatable annotation [%s]",
1341-
containerType.getName(), annotationType.getName());
1341+
containerType.getName(), annotationType.getName());
13421342
throw new AnnotationConfigurationException(msg, ex);
13431343
}
13441344
}

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
@@ -159,7 +159,7 @@ public static <A extends Annotation> A getAnnotation(Annotation ann, Class<A> an
159159
try {
160160
return synthesizeAnnotation(annotatedElement.getAnnotation(annotationType), annotatedElement);
161161
}
162-
catch (Exception ex) {
162+
catch (Throwable ex) {
163163
handleIntrospectionFailure(annotatedElement, ex);
164164
}
165165
return null;
@@ -190,7 +190,7 @@ public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedE
190190
}
191191
return synthesizeAnnotation(annotation, annotatedElement);
192192
}
193-
catch (Exception ex) {
193+
catch (Throwable ex) {
194194
handleIntrospectionFailure(annotatedElement, ex);
195195
}
196196
return null;
@@ -230,7 +230,7 @@ public static Annotation[] getAnnotations(AnnotatedElement annotatedElement) {
230230
try {
231231
return synthesizeAnnotationArray(annotatedElement.getAnnotations(), annotatedElement);
232232
}
233-
catch (Exception ex) {
233+
catch (Throwable ex) {
234234
handleIntrospectionFailure(annotatedElement, ex);
235235
}
236236
return null;
@@ -252,7 +252,7 @@ public static Annotation[] getAnnotations(Method method) {
252252
try {
253253
return synthesizeAnnotationArray(BridgeMethodResolver.findBridgedMethod(method).getAnnotations(), method);
254254
}
255-
catch (Exception ex) {
255+
catch (Throwable ex) {
256256
handleIntrospectionFailure(method, ex);
257257
}
258258
return null;
@@ -471,7 +471,7 @@ private static <A extends Annotation> Set<A> getRepeatableAnnotations(AnnotatedE
471471
}
472472
return new AnnotationCollector<A>(annotationType, containerAnnotationType, declaredMode).getResult(annotatedElement);
473473
}
474-
catch (Exception ex) {
474+
catch (Throwable ex) {
475475
handleIntrospectionFailure(annotatedElement, ex);
476476
}
477477
return Collections.emptySet();
@@ -534,7 +534,7 @@ private static <A extends Annotation> A findAnnotation(
534534
}
535535
}
536536
}
537-
catch (Exception ex) {
537+
catch (Throwable ex) {
538538
handleIntrospectionFailure(annotatedElement, ex);
539539
}
540540
return null;
@@ -633,7 +633,7 @@ static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
633633
break;
634634
}
635635
}
636-
catch (Exception ex) {
636+
catch (Throwable ex) {
637637
handleIntrospectionFailure(ifcMethod, ex);
638638
}
639639
}
@@ -723,7 +723,7 @@ private static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A>
723723
}
724724
}
725725
}
726-
catch (Exception ex) {
726+
catch (Throwable ex) {
727727
handleIntrospectionFailure(clazz, ex);
728728
return null;
729729
}
@@ -840,7 +840,7 @@ public static boolean isAnnotationDeclaredLocally(Class<? extends Annotation> an
840840
}
841841
}
842842
}
843-
catch (Exception ex) {
843+
catch (Throwable ex) {
844844
handleIntrospectionFailure(clazz, ex);
845845
}
846846
return false;
@@ -903,12 +903,11 @@ public static boolean isAnnotationMetaPresent(Class<? extends Annotation> annota
903903
/**
904904
* Determine if the supplied {@link Annotation} is defined in the core JDK
905905
* {@code java.lang.annotation} package.
906-
* @param annotation the annotation to check (never {@code null})
906+
* @param annotation the annotation to check
907907
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
908908
*/
909909
public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
910-
Assert.notNull(annotation, "Annotation must not be null");
911-
return isInJavaLangAnnotationPackage(annotation.annotationType().getName());
910+
return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType().getName()));
912911
}
913912

914913
/**
@@ -919,8 +918,7 @@ public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
919918
* @since 4.2
920919
*/
921920
public static boolean isInJavaLangAnnotationPackage(String annotationType) {
922-
Assert.hasText(annotationType, "annotationType must not be null or empty");
923-
return annotationType.startsWith("java.lang.annotation");
921+
return (annotationType != null && annotationType.startsWith("java.lang.annotation"));
924922
}
925923

926924
/**
@@ -1077,7 +1075,7 @@ static AnnotationAttributes retrieveAnnotationAttributes(Object annotatedElement
10771075
attributes.put(method.getName(),
10781076
adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
10791077
}
1080-
catch (Exception ex) {
1078+
catch (Throwable ex) {
10811079
if (ex instanceof InvocationTargetException) {
10821080
Throwable targetException = ((InvocationTargetException) ex).getTargetException();
10831081
rethrowAnnotationConfigurationException(targetException);
@@ -1492,7 +1490,7 @@ static <A extends Annotation> A synthesizeAnnotation(A annotation, Object annota
14921490
public static <A extends Annotation> A synthesizeAnnotation(Map<String, Object> attributes,
14931491
Class<A> annotationType, AnnotatedElement annotatedElement) {
14941492

1495-
Assert.notNull(annotationType, "annotationType must not be null");
1493+
Assert.notNull(annotationType, "'annotationType' must not be null");
14961494
if (attributes == null) {
14971495
return null;
14981496
}
@@ -1572,7 +1570,7 @@ static Annotation[] synthesizeAnnotationArray(Annotation[] annotations, Object a
15721570
*/
15731571
@SuppressWarnings("unchecked")
15741572
static <A extends Annotation> A[] synthesizeAnnotationArray(Map<String, Object>[] maps, Class<A> annotationType) {
1575-
Assert.notNull(annotationType, "annotationType must not be null");
1573+
Assert.notNull(annotationType, "'annotationType' must not be null");
15761574
if (maps == null) {
15771575
return null;
15781576
}
@@ -1850,7 +1848,7 @@ static void rethrowAnnotationConfigurationException(Throwable ex) {
18501848
* @param ex the exception that we encountered
18511849
* @see #rethrowAnnotationConfigurationException
18521850
*/
1853-
static void handleIntrospectionFailure(AnnotatedElement element, Exception ex) {
1851+
static void handleIntrospectionFailure(AnnotatedElement element, Throwable ex) {
18541852
rethrowAnnotationConfigurationException(ex);
18551853

18561854
Log loggerToUse = logger;
@@ -1962,7 +1960,7 @@ else if (!isInJavaLangAnnotationPackage(ann)) {
19621960
}
19631961
}
19641962
}
1965-
catch (Exception ex) {
1963+
catch (Throwable ex) {
19661964
handleIntrospectionFailure(element, ex);
19671965
}
19681966
}
@@ -1977,7 +1975,7 @@ private List<A> getValue(AnnotatedElement element, Annotation annotation) {
19771975
}
19781976
return synthesizedAnnotations;
19791977
}
1980-
catch (Exception ex) {
1978+
catch (Throwable ex) {
19811979
handleIntrospectionFailure(element, ex);
19821980
}
19831981
// 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)