AnnotatedElementUtils leniently ignores TypeNotPresentExceptions (just like AnnotationUtils)

Also refines logIntrospectionFailure to just log at debug level for meta-annotation introspection failures.

Issue: SPR-12889
(cherry picked from commit e78b086)
This commit is contained in:
Juergen Hoeller 2015-04-04 00:20:16 +02:00
parent bf423b2ca0
commit f1dbe8db27
2 changed files with 73 additions and 47 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -188,6 +188,7 @@ public class AnnotatedElementUtils {
Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) { Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {
if (visited.add(element)) { if (visited.add(element)) {
try {
Annotation[] annotations = Annotation[] annotations =
(traverseClassHierarchy ? element.getDeclaredAnnotations() : element.getAnnotations()); (traverseClassHierarchy ? element.getDeclaredAnnotations() : element.getAnnotations());
for (Annotation annotation : annotations) { for (Annotation annotation : annotations) {
@ -224,6 +225,10 @@ public class AnnotatedElementUtils {
} }
} }
} }
catch (Exception ex) {
AnnotationUtils.logIntrospectionFailure(element, ex);
}
}
return null; return null;
} }
@ -232,7 +237,7 @@ public class AnnotatedElementUtils {
* Callback interface used to process an annotation. * Callback interface used to process an annotation.
* @param <T> the result type * @param <T> the result type
*/ */
private static interface Processor<T> { private interface Processor<T> {
/** /**
* Called to process the annotation. * Called to process the annotation.

View File

@ -613,7 +613,7 @@ public abstract class AnnotationUtils {
value = ((Class<?>) value).getName(); value = ((Class<?>) value).getName();
} }
else if (value instanceof Class[]) { else if (value instanceof Class[]) {
Class<?>[] clazzArray = (Class[]) value; Class<?>[] clazzArray = (Class<?>[]) value;
String[] newValue = new String[clazzArray.length]; String[] newValue = new String[clazzArray.length];
for (int i = 0; i < clazzArray.length; i++) { for (int i = 0; i < clazzArray.length; i++) {
newValue[i] = clazzArray[i].getName(); newValue[i] = clazzArray[i].getName();
@ -726,14 +726,30 @@ public abstract class AnnotationUtils {
} }
private static void logIntrospectionFailure(AnnotatedElement annotatedElement, Exception ex) { /**
* Log an introspection failure (in particular {@code TypeNotPresentExceptions}) -
* before moving on, pretending there were no annotations on this specific element.
* @param element the element that we tried to introspect annotations on
* @param ex the exception that we encountered
*/
static void logIntrospectionFailure(AnnotatedElement element, Exception ex) {
Log loggerToUse = logger; Log loggerToUse = logger;
if (loggerToUse == null) { if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(AnnotationUtils.class); loggerToUse = LogFactory.getLog(AnnotationUtils.class);
logger = loggerToUse; logger = loggerToUse;
} }
if (element instanceof Class && Annotation.class.isAssignableFrom((Class<?>) element)) {
// Meta-annotation lookup on an annotation type
if (logger.isDebugEnabled()) {
logger.debug("Failed to introspect meta-annotations on [" + element + "]: " + ex);
}
}
else {
// Direct annotation lookup on regular Class, Method, Field
if (loggerToUse.isInfoEnabled()) { if (loggerToUse.isInfoEnabled()) {
loggerToUse.info("Failed to introspect annotations on [" + annotatedElement + "]: " + ex); logger.info("Failed to introspect annotations on [" + element + "]: " + ex);
}
} }
} }
@ -793,9 +809,10 @@ public abstract class AnnotationUtils {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void process(AnnotatedElement annotatedElement) { private void process(AnnotatedElement element) {
if (this.visited.add(annotatedElement)) { if (this.visited.add(element)) {
for (Annotation ann : annotatedElement.getAnnotations()) { try {
for (Annotation ann : element.getAnnotations()) {
if (ObjectUtils.nullSafeEquals(this.annotationType, ann.annotationType())) { if (ObjectUtils.nullSafeEquals(this.annotationType, ann.annotationType())) {
this.result.add((A) ann); this.result.add((A) ann);
} }
@ -807,6 +824,10 @@ public abstract class AnnotationUtils {
} }
} }
} }
catch (Exception ex) {
logIntrospectionFailure(element, ex);
}
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")