Browse Source

Consistent catching of Throwable for introspection failures

Issue: SPR-12889
pull/1250/merge
Juergen Hoeller 8 years ago
parent
commit
01868096a3
  1. 40
      spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java
  2. 38
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
  3. 2
      spring-core/src/test/java/org/springframework/core/annotation/ComposedRepeatableAnnotationsTests.java

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

@ -151,7 +151,7 @@ public class AnnotatedElementUtils {
*/ */
public static Set<String> getMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) { public static Set<String> getMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
return getMetaAnnotationTypes(element, element.getAnnotation(annotationType)); return getMetaAnnotationTypes(element, element.getAnnotation(annotationType));
} }
@ -213,7 +213,7 @@ public class AnnotatedElementUtils {
*/ */
public static boolean hasMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) { public static boolean hasMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
return hasMetaAnnotationTypes(element, annotationType, null); return hasMetaAnnotationTypes(element, annotationType, null);
} }
@ -266,7 +266,7 @@ public class AnnotatedElementUtils {
*/ */
public static boolean isAnnotated(AnnotatedElement element, Class<? extends Annotation> annotationType) { public static boolean isAnnotated(AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
// Shortcut: directly present on the element, with no processing needed? // Shortcut: directly present on the element, with no processing needed?
if (element.isAnnotationPresent(annotationType)) { if (element.isAnnotationPresent(annotationType)) {
@ -315,7 +315,7 @@ public class AnnotatedElementUtils {
public static AnnotationAttributes getMergedAnnotationAttributes( public static AnnotationAttributes getMergedAnnotationAttributes(
AnnotatedElement element, Class<? extends Annotation> annotationType) { AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
AnnotationAttributes attributes = searchWithGetSemantics(element, annotationType, null, AnnotationAttributes attributes = searchWithGetSemantics(element, annotationType, null,
new MergedAnnotationAttributesProcessor()); new MergedAnnotationAttributesProcessor());
AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false); AnnotationUtils.postProcessAnnotationAttributes(element, attributes, false, false);
@ -399,7 +399,7 @@ public class AnnotatedElementUtils {
* @see AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement) * @see AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)
*/ */
public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) { public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
// Shortcut: directly present on the element, with no merging needed? // Shortcut: directly present on the element, with no merging needed?
if (!(element instanceof Class)) { if (!(element instanceof Class)) {
@ -440,7 +440,7 @@ public class AnnotatedElementUtils {
Class<A> annotationType) { Class<A> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true); MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true);
searchWithGetSemantics(element, annotationType, null, processor); searchWithGetSemantics(element, annotationType, null, processor);
@ -507,7 +507,7 @@ public class AnnotatedElementUtils {
Class<A> annotationType, Class<? extends Annotation> containerType) { Class<A> annotationType, Class<? extends Annotation> containerType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
if (containerType == null) { if (containerType == null) {
containerType = resolveContainerType(annotationType); containerType = resolveContainerType(annotationType);
@ -593,7 +593,7 @@ public class AnnotatedElementUtils {
*/ */
public static boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) { public static boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
// Shortcut: directly present on the element, with no processing needed? // Shortcut: directly present on the element, with no processing needed?
if (element.isAnnotationPresent(annotationType)) { if (element.isAnnotationPresent(annotationType)) {
@ -696,7 +696,7 @@ public class AnnotatedElementUtils {
* @see #getMergedAnnotationAttributes(AnnotatedElement, Class) * @see #getMergedAnnotationAttributes(AnnotatedElement, Class)
*/ */
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) { public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
// Shortcut: directly present on the element, with no merging needed? // Shortcut: directly present on the element, with no merging needed?
if (!(element instanceof Class)) { if (!(element instanceof Class)) {
@ -736,7 +736,7 @@ public class AnnotatedElementUtils {
Class<A> annotationType) { Class<A> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true); MergedAnnotationAttributesProcessor processor = new MergedAnnotationAttributesProcessor(false, false, true);
searchWithFindSemantics(element, annotationType, null, processor); searchWithFindSemantics(element, annotationType, null, processor);
@ -803,7 +803,7 @@ public class AnnotatedElementUtils {
Class<A> annotationType, Class<? extends Annotation> containerType) { Class<A> annotationType, Class<? extends Annotation> containerType) {
Assert.notNull(element, "AnnotatedElement must not be null"); Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
if (containerType == null) { if (containerType == null) {
containerType = resolveContainerType(annotationType); containerType = resolveContainerType(annotationType);
@ -910,7 +910,7 @@ public class AnnotatedElementUtils {
} }
} }
} }
catch (Exception ex) { catch (Throwable ex) {
AnnotationUtils.handleIntrospectionFailure(element, ex); AnnotationUtils.handleIntrospectionFailure(element, ex);
} }
} }
@ -1199,7 +1199,7 @@ public class AnnotatedElementUtils {
} }
} }
} }
catch (Exception ex) { catch (Throwable ex) {
AnnotationUtils.handleIntrospectionFailure(element, ex); AnnotationUtils.handleIntrospectionFailure(element, ex);
} }
} }
@ -1241,7 +1241,7 @@ public class AnnotatedElementUtils {
try { try {
return (A[]) AnnotationUtils.getValue(container); return (A[]) AnnotationUtils.getValue(container);
} }
catch (Exception ex) { catch (Throwable ex) {
AnnotationUtils.handleIntrospectionFailure(element, ex); AnnotationUtils.handleIntrospectionFailure(element, ex);
} }
// Unable to read value from repeating annotation container -> ignore it. // Unable to read value from repeating annotation container -> ignore it.
@ -1260,8 +1260,8 @@ public class AnnotatedElementUtils {
Class<? extends Annotation> containerType = AnnotationUtils.resolveContainerAnnotationType(annotationType); Class<? extends Annotation> containerType = AnnotationUtils.resolveContainerAnnotationType(annotationType);
if (containerType == null) { if (containerType == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"annotationType must be a repeatable annotation: failed to resolve container type for " "Annotation type must be a repeatable annotation: failed to resolve container type for " +
+ annotationType.getName()); annotationType.getName());
} }
return containerType; return containerType;
} }
@ -1283,15 +1283,15 @@ public class AnnotatedElementUtils {
Class<?> returnType = method.getReturnType(); Class<?> returnType = method.getReturnType();
if (!returnType.isArray() || returnType.getComponentType() != annotationType) { if (!returnType.isArray() || returnType.getComponentType() != annotationType) {
String msg = String.format( String msg = String.format(
"Container type [%s] must declare a 'value' attribute for an array of type [%s]", "Container type [%s] must declare a 'value' attribute for an array of type [%s]",
containerType.getName(), annotationType.getName()); containerType.getName(), annotationType.getName());
throw new AnnotationConfigurationException(msg); throw new AnnotationConfigurationException(msg);
} }
} }
catch (Exception ex) { catch (Throwable ex) {
AnnotationUtils.rethrowAnnotationConfigurationException(ex); AnnotationUtils.rethrowAnnotationConfigurationException(ex);
String msg = String.format("Invalid declaration of container type [%s] for repeatable annotation [%s]", String msg = String.format("Invalid declaration of container type [%s] for repeatable annotation [%s]",
containerType.getName(), annotationType.getName()); containerType.getName(), annotationType.getName());
throw new AnnotationConfigurationException(msg, ex); throw new AnnotationConfigurationException(msg, ex);
} }
} }

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

@ -158,7 +158,7 @@ public abstract class AnnotationUtils {
try { try {
return synthesizeAnnotation(annotatedElement.getAnnotation(annotationType), annotatedElement); return synthesizeAnnotation(annotatedElement.getAnnotation(annotationType), annotatedElement);
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex); handleIntrospectionFailure(annotatedElement, ex);
} }
return null; return null;
@ -189,7 +189,7 @@ public abstract class AnnotationUtils {
} }
return synthesizeAnnotation(annotation, annotatedElement); return synthesizeAnnotation(annotation, annotatedElement);
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex); handleIntrospectionFailure(annotatedElement, ex);
} }
return null; return null;
@ -229,7 +229,7 @@ public abstract class AnnotationUtils {
try { try {
return synthesizeAnnotationArray(annotatedElement.getAnnotations(), annotatedElement); return synthesizeAnnotationArray(annotatedElement.getAnnotations(), annotatedElement);
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex); handleIntrospectionFailure(annotatedElement, ex);
} }
return null; return null;
@ -251,7 +251,7 @@ public abstract class AnnotationUtils {
try { try {
return synthesizeAnnotationArray(BridgeMethodResolver.findBridgedMethod(method).getAnnotations(), method); return synthesizeAnnotationArray(BridgeMethodResolver.findBridgedMethod(method).getAnnotations(), method);
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(method, ex); handleIntrospectionFailure(method, ex);
} }
return null; return null;
@ -440,7 +440,7 @@ public abstract class AnnotationUtils {
} }
return new AnnotationCollector<>(annotationType, containerAnnotationType, declaredMode).getResult(annotatedElement); return new AnnotationCollector<>(annotationType, containerAnnotationType, declaredMode).getResult(annotatedElement);
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex); handleIntrospectionFailure(annotatedElement, ex);
} }
return Collections.emptySet(); return Collections.emptySet();
@ -503,7 +503,7 @@ public abstract class AnnotationUtils {
} }
} }
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex); handleIntrospectionFailure(annotatedElement, ex);
} }
return null; return null;
@ -602,7 +602,7 @@ public abstract class AnnotationUtils {
break; break;
} }
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(ifcMethod, ex); handleIntrospectionFailure(ifcMethod, ex);
} }
} }
@ -692,7 +692,7 @@ public abstract class AnnotationUtils {
} }
} }
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(clazz, ex); handleIntrospectionFailure(clazz, ex);
return null; return null;
} }
@ -809,7 +809,7 @@ public abstract class AnnotationUtils {
} }
} }
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(clazz, ex); handleIntrospectionFailure(clazz, ex);
} }
return false; return false;
@ -872,12 +872,11 @@ public abstract class AnnotationUtils {
/** /**
* Determine if the supplied {@link Annotation} is defined in the core JDK * Determine if the supplied {@link Annotation} is defined in the core JDK
* {@code java.lang.annotation} package. * {@code java.lang.annotation} package.
* @param annotation the annotation to check (never {@code null}) * @param annotation the annotation to check
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package * @return {@code true} if the annotation is in the {@code java.lang.annotation} package
*/ */
public static boolean isInJavaLangAnnotationPackage(Annotation annotation) { public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
Assert.notNull(annotation, "Annotation must not be null"); return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType().getName()));
return isInJavaLangAnnotationPackage(annotation.annotationType().getName());
} }
/** /**
@ -888,8 +887,7 @@ public abstract class AnnotationUtils {
* @since 4.2 * @since 4.2
*/ */
public static boolean isInJavaLangAnnotationPackage(String annotationType) { public static boolean isInJavaLangAnnotationPackage(String annotationType) {
Assert.hasText(annotationType, "annotationType must not be null or empty"); return (annotationType != null && annotationType.startsWith("java.lang.annotation"));
return annotationType.startsWith("java.lang.annotation");
} }
/** /**
@ -1046,7 +1044,7 @@ public abstract class AnnotationUtils {
attributes.put(method.getName(), attributes.put(method.getName(),
adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap)); adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
} }
catch (Exception ex) { catch (Throwable ex) {
if (ex instanceof InvocationTargetException) { if (ex instanceof InvocationTargetException) {
Throwable targetException = ((InvocationTargetException) ex).getTargetException(); Throwable targetException = ((InvocationTargetException) ex).getTargetException();
rethrowAnnotationConfigurationException(targetException); rethrowAnnotationConfigurationException(targetException);
@ -1461,7 +1459,7 @@ public abstract class AnnotationUtils {
public static <A extends Annotation> A synthesizeAnnotation(Map<String, Object> attributes, public static <A extends Annotation> A synthesizeAnnotation(Map<String, Object> attributes,
Class<A> annotationType, AnnotatedElement annotatedElement) { Class<A> annotationType, AnnotatedElement annotatedElement) {
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
if (attributes == null) { if (attributes == null) {
return null; return null;
} }
@ -1541,7 +1539,7 @@ public abstract class AnnotationUtils {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static <A extends Annotation> A[] synthesizeAnnotationArray(Map<String, Object>[] maps, Class<A> annotationType) { static <A extends Annotation> A[] synthesizeAnnotationArray(Map<String, Object>[] maps, Class<A> annotationType) {
Assert.notNull(annotationType, "annotationType must not be null"); Assert.notNull(annotationType, "'annotationType' must not be null");
if (maps == null) { if (maps == null) {
return null; return null;
} }
@ -1809,7 +1807,7 @@ public abstract class AnnotationUtils {
* @param ex the exception that we encountered * @param ex the exception that we encountered
* @see #rethrowAnnotationConfigurationException * @see #rethrowAnnotationConfigurationException
*/ */
static void handleIntrospectionFailure(AnnotatedElement element, Exception ex) { static void handleIntrospectionFailure(AnnotatedElement element, Throwable ex) {
rethrowAnnotationConfigurationException(ex); rethrowAnnotationConfigurationException(ex);
Log loggerToUse = logger; Log loggerToUse = logger;
@ -1921,7 +1919,7 @@ public abstract class AnnotationUtils {
} }
} }
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(element, ex); handleIntrospectionFailure(element, ex);
} }
} }
@ -1936,7 +1934,7 @@ public abstract class AnnotationUtils {
} }
return synthesizedAnnotations; return synthesizedAnnotations;
} }
catch (Exception ex) { catch (Throwable ex) {
handleIntrospectionFailure(element, ex); handleIntrospectionFailure(element, ex);
} }
// Unable to read value from repeating annotation container -> ignore it. // Unable to read value from repeating annotation container -> ignore it.

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

@ -186,7 +186,7 @@ public class ComposedRepeatableAnnotationsTests {
private void expectNonRepeatableAnnotation() { private void expectNonRepeatableAnnotation() {
exception.expect(IllegalArgumentException.class); exception.expect(IllegalArgumentException.class);
exception.expectMessage(startsWith("annotationType must be a repeatable annotation")); exception.expectMessage(startsWith("Annotation type must be a repeatable annotation"));
exception.expectMessage(containsString("failed to resolve container type for")); exception.expectMessage(containsString("failed to resolve container type for"));
exception.expectMessage(containsString(NonRepeatable.class.getName())); exception.expectMessage(containsString(NonRepeatable.class.getName()));
} }

Loading…
Cancel
Save