28
28
import java .util .Set ;
29
29
import java .util .WeakHashMap ;
30
30
31
+ import org .apache .commons .logging .Log ;
32
+ import org .apache .commons .logging .LogFactory ;
33
+
31
34
import org .springframework .core .BridgeMethodResolver ;
32
35
import org .springframework .util .Assert ;
33
36
import org .springframework .util .ObjectUtils ;
@@ -63,6 +66,8 @@ public abstract class AnnotationUtils {
63
66
/** The attribute name for annotations with a single element */
64
67
public static final String VALUE = "value" ;
65
68
69
+ private static final Log logger = LogFactory .getLog (AnnotationUtils .class );
70
+
66
71
private static final Map <Class <?>, Boolean > annotatedInterfaceCache = new WeakHashMap <Class <?>, Boolean >();
67
72
68
73
@@ -79,29 +84,49 @@ public static <T extends Annotation> T getAnnotation(Annotation ann, Class<T> an
79
84
if (annotationType .isInstance (ann )) {
80
85
return (T ) ann ;
81
86
}
82
- return ann .annotationType ().getAnnotation (annotationType );
87
+ try {
88
+ return ann .annotationType ().getAnnotation (annotationType );
89
+ }
90
+ catch (Exception ex ) {
91
+ // Assuming nested Class values not resolvable within annotation attributes...
92
+ // We're probably hitting a non-present optional arrangement - let's back out.
93
+ if (logger .isInfoEnabled ()) {
94
+ logger .info ("Failed to introspect annotations on [" + ann .annotationType () + "]: " + ex );
95
+ }
96
+ return null ;
97
+ }
83
98
}
84
99
85
100
/**
86
101
* Get a single {@link Annotation} of {@code annotationType} from the supplied
87
102
* Method, Constructor or Field. Meta-annotations will be searched if the annotation
88
103
* is not declared locally on the supplied element.
89
- * @param ae the Method, Constructor or Field from which to get the annotation
104
+ * @param annotatedElement the Method, Constructor or Field from which to get the annotation
90
105
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
91
106
* @return the matching annotation, or {@code null} if none found
92
107
* @since 3.1
93
108
*/
94
- public static <T extends Annotation > T getAnnotation (AnnotatedElement ae , Class <T > annotationType ) {
95
- T ann = ae .getAnnotation (annotationType );
96
- if (ann == null ) {
97
- for (Annotation metaAnn : ae .getAnnotations ()) {
98
- ann = metaAnn .annotationType ().getAnnotation (annotationType );
99
- if (ann != null ) {
100
- break ;
109
+ public static <T extends Annotation > T getAnnotation (AnnotatedElement annotatedElement , Class <T > annotationType ) {
110
+ try {
111
+ T ann = annotatedElement .getAnnotation (annotationType );
112
+ if (ann == null ) {
113
+ for (Annotation metaAnn : annotatedElement .getAnnotations ()) {
114
+ ann = metaAnn .annotationType ().getAnnotation (annotationType );
115
+ if (ann != null ) {
116
+ break ;
117
+ }
101
118
}
102
119
}
120
+ return ann ;
121
+ }
122
+ catch (Exception ex ) {
123
+ // Assuming nested Class values not resolvable within annotation attributes...
124
+ // We're probably hitting a non-present optional arrangement - let's back out.
125
+ if (logger .isInfoEnabled ()) {
126
+ logger .info ("Failed to introspect annotations on [" + annotatedElement + "]: " + ex );
127
+ }
128
+ return null ;
103
129
}
104
- return ann ;
105
130
}
106
131
107
132
/**
@@ -112,7 +137,17 @@ public static <T extends Annotation> T getAnnotation(AnnotatedElement ae, Class<
112
137
* @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method)
113
138
*/
114
139
public static Annotation [] getAnnotations (Method method ) {
115
- return BridgeMethodResolver .findBridgedMethod (method ).getAnnotations ();
140
+ try {
141
+ return BridgeMethodResolver .findBridgedMethod (method ).getAnnotations ();
142
+ }
143
+ catch (Exception ex ) {
144
+ // Assuming nested Class values not resolvable within annotation attributes...
145
+ // We're probably hitting a non-present optional arrangement - let's back out.
146
+ if (logger .isInfoEnabled ()) {
147
+ logger .info ("Failed to introspect annotations on [" + method + "]: " + ex );
148
+ }
149
+ return null ;
150
+ }
116
151
}
117
152
118
153
/**
@@ -162,10 +197,19 @@ public static <A extends Annotation> Set<A> getRepeatableAnnotation(Method metho
162
197
public static <A extends Annotation > Set <A > getRepeatableAnnotation (AnnotatedElement annotatedElement ,
163
198
Class <? extends Annotation > containerAnnotationType , Class <A > annotationType ) {
164
199
165
- if (annotatedElement .getAnnotations ().length == 0 ) {
166
- return Collections .emptySet ();
200
+ try {
201
+ if (annotatedElement .getAnnotations ().length > 0 ) {
202
+ return new AnnotationCollector <A >(containerAnnotationType , annotationType ).getResult (annotatedElement );
203
+ }
204
+ }
205
+ catch (Exception ex ) {
206
+ // Assuming nested Class values not resolvable within annotation attributes...
207
+ // We're probably hitting a non-present optional arrangement - let's back out.
208
+ if (logger .isInfoEnabled ()) {
209
+ logger .info ("Failed to introspect annotations on [" + annotatedElement + "]: " + ex );
210
+ }
167
211
}
168
- return new AnnotationCollector < A >( containerAnnotationType , annotationType ). getResult ( annotatedElement );
212
+ return Collections . emptySet ( );
169
213
}
170
214
171
215
/**
@@ -230,9 +274,18 @@ private static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
230
274
}
231
275
boolean found = false ;
232
276
for (Method ifcMethod : iface .getMethods ()) {
233
- if (ifcMethod .getAnnotations ().length > 0 ) {
234
- found = true ;
235
- break ;
277
+ try {
278
+ if (ifcMethod .getAnnotations ().length > 0 ) {
279
+ found = true ;
280
+ break ;
281
+ }
282
+ }
283
+ catch (Exception ex ) {
284
+ // Assuming nested Class values not resolvable within annotation attributes...
285
+ // We're probably hitting a non-present optional arrangement - let's back out.
286
+ if (logger .isInfoEnabled ()) {
287
+ logger .info ("Failed to introspect annotations on [" + ifcMethod + "]: " + ex );
288
+ }
236
289
}
237
290
}
238
291
annotatedInterfaceCache .put (iface , found );
@@ -278,7 +331,17 @@ public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> a
278
331
private static <A extends Annotation > A findAnnotation (Class <?> clazz , Class <A > annotationType , Set <Annotation > visited ) {
279
332
Assert .notNull (clazz , "Class must not be null" );
280
333
if (isAnnotationDeclaredLocally (annotationType , clazz )) {
281
- return clazz .getAnnotation (annotationType );
334
+ try {
335
+ return clazz .getAnnotation (annotationType );
336
+ }
337
+ catch (Exception ex ) {
338
+ // Assuming nested Class values not resolvable within annotation attributes...
339
+ // We're probably hitting a non-present optional arrangement - let's back out.
340
+ if (logger .isInfoEnabled ()) {
341
+ logger .info ("Failed to introspect annotations on [" + clazz + "]: " + ex );
342
+ }
343
+ return null ;
344
+ }
282
345
}
283
346
for (Class <?> ifc : clazz .getInterfaces ()) {
284
347
A annotation = findAnnotation (ifc , annotationType , visited );
@@ -390,10 +453,19 @@ public static boolean isAnnotationDeclaredLocally(Class<? extends Annotation> an
390
453
Assert .notNull (annotationType , "Annotation type must not be null" );
391
454
Assert .notNull (clazz , "Class must not be null" );
392
455
boolean declaredLocally = false ;
393
- for (Annotation annotation : clazz .getDeclaredAnnotations ()) {
394
- if (annotation .annotationType ().equals (annotationType )) {
395
- declaredLocally = true ;
396
- break ;
456
+ try {
457
+ for (Annotation annotation : clazz .getDeclaredAnnotations ()) {
458
+ if (annotation .annotationType ().equals (annotationType )) {
459
+ declaredLocally = true ;
460
+ break ;
461
+ }
462
+ }
463
+ }
464
+ catch (Exception ex ) {
465
+ // Assuming nested Class values not resolvable within annotation attributes...
466
+ // We're probably hitting a non-present optional arrangement - let's back out.
467
+ if (logger .isInfoEnabled ()) {
468
+ logger .info ("Failed to introspect annotations on [" + clazz + "]: " + ex );
397
469
}
398
470
}
399
471
return declaredLocally ;
@@ -502,7 +574,7 @@ else if (value instanceof Class[]) {
502
574
}
503
575
if (nestedAnnotationsAsMap && value instanceof Annotation ) {
504
576
attrs .put (method .getName (),
505
- getAnnotationAttributes ((Annotation ) value , classValuesAsString , true ));
577
+ getAnnotationAttributes ((Annotation ) value , classValuesAsString , true ));
506
578
}
507
579
else if (nestedAnnotationsAsMap && value instanceof Annotation []) {
508
580
Annotation [] realAnnotations = (Annotation []) value ;
@@ -632,7 +704,7 @@ private void process(AnnotatedElement annotatedElement) {
632
704
this .result .add ((A ) annotation );
633
705
}
634
706
else if (ObjectUtils .nullSafeEquals (this .containerAnnotationType , annotation .annotationType ())) {
635
- this .result .addAll (Arrays . asList ( getValue (annotation ) ));
707
+ this .result .addAll (getValue (annotation ));
636
708
}
637
709
else if (!isInJavaLangAnnotationPackage (annotation )) {
638
710
process (annotation .annotationType ());
@@ -642,15 +714,15 @@ else if (!isInJavaLangAnnotationPackage(annotation)) {
642
714
}
643
715
644
716
@ SuppressWarnings ("unchecked" )
645
- private A [] getValue (Annotation annotation ) {
717
+ private List < A > getValue (Annotation annotation ) {
646
718
try {
647
719
Method method = annotation .annotationType ().getDeclaredMethod ("value" );
648
720
ReflectionUtils .makeAccessible (method );
649
- return ( A []) method .invoke (annotation );
721
+ return Arrays . asList (( A []) method .invoke (annotation ) );
650
722
}
651
723
catch (Exception ex ) {
652
- throw new IllegalStateException ( " Unable to read value from repeating annotation container " +
653
- this . containerAnnotationType . getName (), ex );
724
+ // Unable to read value from repeating annotation container -> ignore it.
725
+ return Collections . emptyList ( );
654
726
}
655
727
}
656
728
}
0 commit comments