diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 92eaf8ef974..bd0e9e37fa9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -355,16 +355,22 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz) { - // Quick check on the concurrent map first, with minimal locking. // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); + // Quick check on the concurrent map first, with minimal locking. InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { - metadata = buildAutowiringMetadata(clazz); - this.injectionMetadataCache.put(cacheKey, metadata); + try { + metadata = buildAutowiringMetadata(clazz); + this.injectionMetadataCache.put(cacheKey, metadata); + } + catch (NoClassDefFoundError err) { + throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + + "] for autowiring metadata: could not find class that it depends on", err); + } } } } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index 2f6d981467c..2b911799796 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -311,89 +311,99 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean private InjectionMetadata findResourceMetadata(String beanName, final Class clazz) { - // Quick check on the concurrent map first, with minimal locking. // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); + // Quick check on the concurrent map first, with minimal locking. InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { - LinkedList elements = new LinkedList(); - Class targetClass = clazz; - - do { - LinkedList currElements = new LinkedList(); - for (Field field : targetClass.getDeclaredFields()) { - if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { - if (Modifier.isStatic(field.getModifiers())) { - throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields"); - } - currElements.add(new WebServiceRefElement(field, null)); - } - else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) { - if (Modifier.isStatic(field.getModifiers())) { - throw new IllegalStateException("@EJB annotation is not supported on static fields"); - } - currElements.add(new EjbRefElement(field, null)); - } - else if (field.isAnnotationPresent(Resource.class)) { - if (Modifier.isStatic(field.getModifiers())) { - throw new IllegalStateException("@Resource annotation is not supported on static fields"); - } - if (!ignoredResourceTypes.contains(field.getType().getName())) { - currElements.add(new ResourceElement(field, null)); - } - } + try { + metadata = buildResourceMetadata(clazz); + this.injectionMetadataCache.put(cacheKey, metadata); + } + catch (NoClassDefFoundError err) { + throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + + "] for resource metadata: could not find class that it depends on", err); + } + } + } + } + return metadata; + } + + private InjectionMetadata buildResourceMetadata(Class clazz) { + LinkedList elements = new LinkedList(); + Class targetClass = clazz; + + do { + LinkedList currElements = new LinkedList(); + for (Field field : targetClass.getDeclaredFields()) { + if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields"); + } + currElements.add(new WebServiceRefElement(field, null)); + } + else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("@EJB annotation is not supported on static fields"); + } + currElements.add(new EjbRefElement(field, null)); + } + else if (field.isAnnotationPresent(Resource.class)) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("@Resource annotation is not supported on static fields"); + } + if (!ignoredResourceTypes.contains(field.getType().getName())) { + currElements.add(new ResourceElement(field, null)); + } + } + } + for (Method method : targetClass.getDeclaredMethods()) { + if (!method.isBridge() && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { + if (webServiceRefClass != null && method.isAnnotationPresent(webServiceRefClass)) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods"); } - for (Method method : targetClass.getDeclaredMethods()) { - if (!method.isBridge() && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { - if (webServiceRefClass != null && method.isAnnotationPresent(webServiceRefClass)) { - if (Modifier.isStatic(method.getModifiers())) { - throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods"); - } - if (method.getParameterTypes().length != 1) { - throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method); - } - PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); - currElements.add(new WebServiceRefElement(method, pd)); - } - else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass)) { - if (Modifier.isStatic(method.getModifiers())) { - throw new IllegalStateException("@EJB annotation is not supported on static methods"); - } - if (method.getParameterTypes().length != 1) { - throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method); - } - PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); - currElements.add(new EjbRefElement(method, pd)); - } - else if (method.isAnnotationPresent(Resource.class)) { - if (Modifier.isStatic(method.getModifiers())) { - throw new IllegalStateException("@Resource annotation is not supported on static methods"); - } - Class[] paramTypes = method.getParameterTypes(); - if (paramTypes.length != 1) { - throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method); - } - if (!ignoredResourceTypes.contains(paramTypes[0].getName())) { - PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); - currElements.add(new ResourceElement(method, pd)); - } - } - } + if (method.getParameterTypes().length != 1) { + throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method); + } + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + currElements.add(new WebServiceRefElement(method, pd)); + } + else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass)) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("@EJB annotation is not supported on static methods"); + } + if (method.getParameterTypes().length != 1) { + throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method); + } + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + currElements.add(new EjbRefElement(method, pd)); + } + else if (method.isAnnotationPresent(Resource.class)) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("@Resource annotation is not supported on static methods"); + } + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length != 1) { + throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method); + } + if (!ignoredResourceTypes.contains(paramTypes[0].getName())) { + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + currElements.add(new ResourceElement(method, pd)); } - elements.addAll(0, currElements); - targetClass = targetClass.getSuperclass(); } - while (targetClass != null && targetClass != Object.class); - - metadata = new InjectionMetadata(clazz, elements); - this.injectionMetadataCache.put(cacheKey, metadata); } } + elements.addAll(0, currElements); + targetClass = targetClass.getSuperclass(); } - return metadata; + while (targetClass != null && targetClass != Object.class); + + return new InjectionMetadata(clazz, elements); } /** diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index f35bc6c8a7e..a35d7cfdd60 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -376,57 +376,67 @@ public class PersistenceAnnotationBeanPostProcessor private InjectionMetadata findPersistenceMetadata(String beanName, final Class clazz) { - // Quick check on the concurrent map first, with minimal locking. // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); + // Quick check on the concurrent map first, with minimal locking. InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { - LinkedList elements = new LinkedList(); - Class targetClass = clazz; - - do { - LinkedList currElements = new LinkedList(); - for (Field field : targetClass.getDeclaredFields()) { - PersistenceContext pc = field.getAnnotation(PersistenceContext.class); - PersistenceUnit pu = field.getAnnotation(PersistenceUnit.class); - if (pc != null || pu != null) { - if (Modifier.isStatic(field.getModifiers())) { - throw new IllegalStateException("Persistence annotations are not supported on static fields"); - } - currElements.add(new PersistenceElement(field, null)); - } - } - for (Method method : targetClass.getDeclaredMethods()) { - PersistenceContext pc = method.getAnnotation(PersistenceContext.class); - PersistenceUnit pu = method.getAnnotation(PersistenceUnit.class); - if ((pc != null || pu != null) && !method.isBridge() && - method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { - if (Modifier.isStatic(method.getModifiers())) { - throw new IllegalStateException("Persistence annotations are not supported on static methods"); - } - if (method.getParameterTypes().length != 1) { - throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method); - } - PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); - currElements.add(new PersistenceElement(method, pd)); - } - } - elements.addAll(0, currElements); - targetClass = targetClass.getSuperclass(); + try { + metadata = buildPersistenceMetadata(clazz); + this.injectionMetadataCache.put(cacheKey, metadata); + } + catch (NoClassDefFoundError err) { + throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() + + "] for persistence metadata: could not find class that it depends on", err); } - while (targetClass != null && targetClass != Object.class); - - metadata = new InjectionMetadata(clazz, elements); - this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; } + private InjectionMetadata buildPersistenceMetadata(Class clazz) { + LinkedList elements = new LinkedList(); + Class targetClass = clazz; + + do { + LinkedList currElements = new LinkedList(); + for (Field field : targetClass.getDeclaredFields()) { + PersistenceContext pc = field.getAnnotation(PersistenceContext.class); + PersistenceUnit pu = field.getAnnotation(PersistenceUnit.class); + if (pc != null || pu != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("Persistence annotations are not supported on static fields"); + } + currElements.add(new PersistenceElement(field, null)); + } + } + for (Method method : targetClass.getDeclaredMethods()) { + PersistenceContext pc = method.getAnnotation(PersistenceContext.class); + PersistenceUnit pu = method.getAnnotation(PersistenceUnit.class); + if ((pc != null || pu != null) && !method.isBridge() && + method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Persistence annotations are not supported on static methods"); + } + if (method.getParameterTypes().length != 1) { + throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method); + } + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + currElements.add(new PersistenceElement(method, pd)); + } + } + elements.addAll(0, currElements); + targetClass = targetClass.getSuperclass(); + } + while (targetClass != null && targetClass != Object.class); + + return new InjectionMetadata(clazz, elements); + } + /** * Return a specified persistence unit for the given unit name, * as defined through the "persistenceUnits" map.