Consistent throwing of BeanCreationExceptions (and reflection exceptions)
Issue: SPR-14883
This commit is contained in:
		
							parent
							
								
									fd7045adac
								
							
						
					
					
						commit
						b42d731fc8
					
				|  | @ -220,7 +220,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void setBeanFactory(BeanFactory beanFactory) throws BeansException { | ||||
| 	public void setBeanFactory(BeanFactory beanFactory) { | ||||
| 		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { | ||||
| 			throw new IllegalArgumentException( | ||||
| 					"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory"); | ||||
|  | @ -238,7 +238,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeansException { | ||||
| 	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) | ||||
| 			throws BeanCreationException { | ||||
| 
 | ||||
| 		// Let's check for lookup methods here.. | ||||
| 		if (!this.lookupMethodsChecked.contains(beanName)) { | ||||
| 			ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() { | ||||
| 				@Override | ||||
|  | @ -263,10 +266,19 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 		// Quick check on the concurrent map first, with minimal locking. | ||||
| 		Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); | ||||
| 		if (candidateConstructors == null) { | ||||
| 			// Fully synchronized resolution now... | ||||
| 			synchronized (this.candidateConstructorsCache) { | ||||
| 				candidateConstructors = this.candidateConstructorsCache.get(beanClass); | ||||
| 				if (candidateConstructors == null) { | ||||
| 					Constructor<?>[] rawCandidates = beanClass.getDeclaredConstructors(); | ||||
| 					Constructor<?>[] rawCandidates; | ||||
| 					try { | ||||
| 						rawCandidates = beanClass.getDeclaredConstructors(); | ||||
| 					} | ||||
| 					catch (Throwable ex) { | ||||
| 						throw new BeanCreationException(beanName, | ||||
| 								"Resolution of declared constructors on bean Class [" + beanClass.getName() + | ||||
| 								"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); | ||||
| 					} | ||||
| 					List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length); | ||||
| 					Constructor<?> requiredConstructor = null; | ||||
| 					Constructor<?> defaultConstructor = null; | ||||
|  | @ -320,9 +332,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 							} | ||||
| 							else if (candidates.size() == 1 && logger.isWarnEnabled()) { | ||||
| 								logger.warn("Inconsistent constructor declaration on bean with name '" + beanName + | ||||
| 										"': single autowire-marked constructor flagged as optional - this constructor " + | ||||
| 										"is effectively required since there is no default constructor to fall back to: " + | ||||
| 										candidates.get(0)); | ||||
| 										"': single autowire-marked constructor flagged as optional - " + | ||||
| 										"this constructor is effectively required since there is no " + | ||||
| 										"default constructor to fall back to: " + candidates.get(0)); | ||||
| 							} | ||||
| 						} | ||||
| 						candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]); | ||||
|  | @ -342,7 +354,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 
 | ||||
| 	@Override | ||||
| 	public PropertyValues postProcessPropertyValues( | ||||
| 			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { | ||||
| 			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { | ||||
| 
 | ||||
| 		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); | ||||
| 		try { | ||||
|  | @ -361,9 +373,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 	 * 'Native' processing method for direct calls with an arbitrary target instance, | ||||
| 	 * resolving all of its fields and methods which are annotated with {@code @Autowired}. | ||||
| 	 * @param bean the target instance to process | ||||
| 	 * @throws BeansException if autowiring failed | ||||
| 	 * @throws BeanCreationException if autowiring failed | ||||
| 	 */ | ||||
| 	public void processInjection(Object bean) throws BeansException { | ||||
| 	public void processInjection(Object bean) throws BeanCreationException { | ||||
| 		Class<?> clazz = bean.getClass(); | ||||
| 		InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null); | ||||
| 		try { | ||||
|  | @ -373,7 +385,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 			throw ex; | ||||
| 		} | ||||
| 		catch (Throwable ex) { | ||||
| 			throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex); | ||||
| 			throw new BeanCreationException( | ||||
| 					"Injection of autowired dependencies failed for class [" + clazz + "]", ex); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -446,7 +459,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 						} | ||||
| 						if (method.getParameterTypes().length == 0) { | ||||
| 							if (logger.isWarnEnabled()) { | ||||
| 								logger.warn("Autowired annotation should be used on methods with parameters: " + method); | ||||
| 								logger.warn("Autowired annotation should only be used on methods with parameters: " + | ||||
| 										method); | ||||
| 							} | ||||
| 						} | ||||
| 						boolean required = determineRequiredStatus(ann); | ||||
|  | @ -629,7 +643,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 				Class<?>[] paramTypes = method.getParameterTypes(); | ||||
| 				arguments = new Object[paramTypes.length]; | ||||
| 				DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length]; | ||||
| 				Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length); | ||||
| 				Set<String> autowiredBeans = new LinkedHashSet<String>(paramTypes.length); | ||||
| 				TypeConverter typeConverter = beanFactory.getTypeConverter(); | ||||
| 				for (int i = 0; i < arguments.length; i++) { | ||||
| 					MethodParameter methodParam = new MethodParameter(method, i); | ||||
|  | @ -637,7 +651,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 					currDesc.setContainingClass(bean.getClass()); | ||||
| 					descriptors[i] = currDesc; | ||||
| 					try { | ||||
| 						Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeanNames, typeConverter); | ||||
| 						Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); | ||||
| 						if (arg == null && !this.required) { | ||||
| 							arguments = null; | ||||
| 							break; | ||||
|  | @ -655,9 +669,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 							for (int i = 0; i < arguments.length; i++) { | ||||
| 								this.cachedMethodArguments[i] = descriptors[i]; | ||||
| 							} | ||||
| 							registerDependentBeans(beanName, autowiredBeanNames); | ||||
| 							if (autowiredBeanNames.size() == paramTypes.length) { | ||||
| 								Iterator<String> it = autowiredBeanNames.iterator(); | ||||
| 							registerDependentBeans(beanName, autowiredBeans); | ||||
| 							if (autowiredBeans.size() == paramTypes.length) { | ||||
| 								Iterator<String> it = autowiredBeans.iterator(); | ||||
| 								for (int i = 0; i < paramTypes.length; i++) { | ||||
| 									String autowiredBeanName = it.next(); | ||||
| 									if (beanFactory.containsBean(autowiredBeanName)) { | ||||
|  | @ -706,19 +720,19 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean | |||
| 	@SuppressWarnings("serial") | ||||
| 	private static class ShortcutDependencyDescriptor extends DependencyDescriptor { | ||||
| 
 | ||||
| 		private final String shortcutName; | ||||
| 		private final String shortcut; | ||||
| 
 | ||||
| 		private final Class<?> requiredType; | ||||
| 
 | ||||
| 		public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcutName, Class<?> requiredType) { | ||||
| 		public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class<?> requiredType) { | ||||
| 			super(original); | ||||
| 			this.shortcutName = shortcutName; | ||||
| 			this.shortcut = shortcut; | ||||
| 			this.requiredType = requiredType; | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public Object resolveShortcut(BeanFactory beanFactory) { | ||||
| 			return resolveCandidate(this.shortcutName, this.requiredType, beanFactory); | ||||
| 			return resolveCandidate(this.shortcut, this.requiredType, beanFactory); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /* | ||||
|  * Copyright 2002-2013 the original author or authors. | ||||
|  * Copyright 2002-2016 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  | @ -141,8 +141,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP | |||
| 
 | ||||
| 	@Override | ||||
| 	public PropertyValues postProcessPropertyValues( | ||||
| 			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) | ||||
| 			throws BeansException { | ||||
| 			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { | ||||
| 
 | ||||
| 		if (!this.validatedBeanNames.contains(beanName)) { | ||||
| 			if (!shouldSkip(this.beanFactory, beanName)) { | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /* | ||||
|  * Copyright 2002-2012 the original author or authors. | ||||
|  * Copyright 2002-2016 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  | @ -66,8 +66,7 @@ public abstract class InstantiationAwareBeanPostProcessorAdapter implements Smar | |||
| 
 | ||||
| 	@Override | ||||
| 	public PropertyValues postProcessPropertyValues( | ||||
| 			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) | ||||
| 			throws BeansException { | ||||
| 			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { | ||||
| 
 | ||||
| 		return pvs; | ||||
| 	} | ||||
|  |  | |||
|  | @ -479,12 +479,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 					"BeanPostProcessor before instantiation of bean failed", ex); | ||||
| 		} | ||||
| 
 | ||||
| 		try { | ||||
| 			Object beanInstance = doCreateBean(beanName, mbdToUse, args); | ||||
| 			if (logger.isDebugEnabled()) { | ||||
| 				logger.debug("Finished creating instance of bean '" + beanName + "'"); | ||||
| 			} | ||||
| 			return beanInstance; | ||||
| 		} | ||||
| 		catch (BeanCreationException ex) { | ||||
| 			// A previously detected exception with proper bean creation context already... | ||||
| 			throw ex; | ||||
| 		} | ||||
| 		catch (Throwable ex) { | ||||
| 			throw new BeanCreationException( | ||||
| 					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Actually create the specified bean. Pre-creation processing has already happened | ||||
|  | @ -500,7 +510,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 	 * @see #instantiateUsingFactoryMethod | ||||
| 	 * @see #autowireConstructor | ||||
| 	 */ | ||||
| 	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { | ||||
| 	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) | ||||
| 			throws BeanCreationException { | ||||
| 
 | ||||
| 		// Instantiate the bean. | ||||
| 		BeanWrapper instanceWrapper = null; | ||||
| 		if (mbd.isSingleton()) { | ||||
|  | @ -515,7 +527,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 		// Allow post-processors to modify the merged bean definition. | ||||
| 		synchronized (mbd.postProcessingLock) { | ||||
| 			if (!mbd.postProcessed) { | ||||
| 				try { | ||||
| 					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); | ||||
| 				} | ||||
| 				catch (Throwable ex) { | ||||
| 					throw new BeanCreationException(mbd.getResourceDescription(), beanName, | ||||
| 							"Post-processing failed of bean type [" + beanType + "] failed", ex); | ||||
| 				} | ||||
| 				mbd.postProcessed = true; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -550,7 +568,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 				throw (BeanCreationException) ex; | ||||
| 			} | ||||
| 			else { | ||||
| 				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); | ||||
| 				throw new BeanCreationException( | ||||
| 						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -586,7 +605,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 			registerDisposableBeanIfNecessary(beanName, bean, mbd); | ||||
| 		} | ||||
| 		catch (BeanDefinitionValidationException ex) { | ||||
| 			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); | ||||
| 			throw new BeanCreationException( | ||||
| 					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); | ||||
| 		} | ||||
| 
 | ||||
| 		return exposedObject; | ||||
|  | @ -773,10 +793,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 					ReflectionUtils.doWithMethods(fbClass, | ||||
| 							new ReflectionUtils.MethodCallback() { | ||||
| 								@Override | ||||
| 								public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { | ||||
| 								public void doWith(Method method) { | ||||
| 									if (method.getName().equals(factoryMethodName) && | ||||
| 											FactoryBean.class.isAssignableFrom(method.getReturnType())) { | ||||
| 										objectType.value = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class); | ||||
| 										objectType.value = GenericTypeResolver.resolveReturnTypeArgument( | ||||
| 												method, FactoryBean.class); | ||||
| 									} | ||||
| 								} | ||||
| 							}); | ||||
|  | @ -933,7 +954,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) | ||||
| 			throws BeansException { | ||||
| 
 | ||||
| 		try { | ||||
| 		for (BeanPostProcessor bp : getBeanPostProcessors()) { | ||||
| 			if (bp instanceof MergedBeanDefinitionPostProcessor) { | ||||
| 				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; | ||||
|  | @ -941,11 +961,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 		catch (Exception ex) { | ||||
| 			throw new BeanCreationException(mbd.getResourceDescription(), beanName, | ||||
| 					"Post-processing failed of bean type [" + beanType + "] failed", ex); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Apply before-instantiation post-processors, resolving whether there is a | ||||
|  | @ -1107,7 +1122,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 			return bw; | ||||
| 		} | ||||
| 		catch (Throwable ex) { | ||||
| 			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); | ||||
| 			throw new BeanCreationException( | ||||
| 					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1659,7 +1675,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac | |||
| 	 * methods with arguments. | ||||
| 	 * @see #invokeInitMethods | ||||
| 	 */ | ||||
| 	protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { | ||||
| 	protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) | ||||
| 			throws Throwable { | ||||
| 
 | ||||
| 		String initMethodName = mbd.getInitMethodName(); | ||||
| 		final Method initMethod = (mbd.isNonPublicAccessAllowed() ? | ||||
| 				BeanUtils.findMethod(bean.getClass(), initMethodName) : | ||||
|  |  | |||
|  | @ -287,13 +287,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp | |||
| 				// Guarantee initialization of beans that the current bean depends on. | ||||
| 				String[] dependsOn = mbd.getDependsOn(); | ||||
| 				if (dependsOn != null) { | ||||
| 					for (String dependsOnBean : dependsOn) { | ||||
| 						if (isDependent(beanName, dependsOnBean)) { | ||||
| 					for (String dep : dependsOn) { | ||||
| 						if (isDependent(beanName, dep)) { | ||||
| 							throw new BeanCreationException(mbd.getResourceDescription(), beanName, | ||||
| 									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); | ||||
| 									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); | ||||
| 						} | ||||
| 						registerDependentBean(dependsOnBean, beanName); | ||||
| 						getBean(dependsOnBean); | ||||
| 						registerDependentBean(dep, beanName); | ||||
| 						getBean(dep); | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
|  | @ -460,19 +460,19 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp | |||
| 				return false; | ||||
| 			} | ||||
| 			if (isFactoryBean(beanName, mbd)) { | ||||
| 				final FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); | ||||
| 				final FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); | ||||
| 				if (System.getSecurityManager() != null) { | ||||
| 					return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { | ||||
| 						@Override | ||||
| 						public Boolean run() { | ||||
| 							return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) || | ||||
| 									!factoryBean.isSingleton()); | ||||
| 							return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || | ||||
| 									!fb.isSingleton()); | ||||
| 						} | ||||
| 					}, getAccessControlContext()); | ||||
| 				} | ||||
| 				else { | ||||
| 					return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) || | ||||
| 							!factoryBean.isSingleton()); | ||||
| 					return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || | ||||
| 							!fb.isSingleton()); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
|  | @ -1053,11 +1053,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp | |||
| 	 * Destroy the given bean instance (usually a prototype instance | ||||
| 	 * obtained from this factory) according to the given bean definition. | ||||
| 	 * @param beanName the name of the bean definition | ||||
| 	 * @param beanInstance the bean instance to destroy | ||||
| 	 * @param bean the bean instance to destroy | ||||
| 	 * @param mbd the merged bean definition | ||||
| 	 */ | ||||
| 	protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) { | ||||
| 		new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy(); | ||||
| 	protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) { | ||||
| 		new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
|  | @ -1238,12 +1238,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp | |||
| 							pbd = getMergedBeanDefinition(parentBeanName); | ||||
| 						} | ||||
| 						else { | ||||
| 							if (getParentBeanFactory() instanceof ConfigurableBeanFactory) { | ||||
| 								pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName); | ||||
| 							BeanFactory parent = getParentBeanFactory(); | ||||
| 							if (parent instanceof ConfigurableBeanFactory) { | ||||
| 								pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); | ||||
| 							} | ||||
| 							else { | ||||
| 								throw new NoSuchBeanDefinitionException(bd.getParentName(), | ||||
| 										"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName + | ||||
| 								throw new NoSuchBeanDefinitionException(parentBeanName, | ||||
| 										"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + | ||||
| 										"': cannot be resolved without an AbstractBeanFactory parent"); | ||||
| 							} | ||||
| 						} | ||||
|  | @ -1359,12 +1360,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp | |||
| 		catch (ClassNotFoundException ex) { | ||||
| 			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); | ||||
| 		} | ||||
| 		catch (LinkageError err) { | ||||
| 			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); | ||||
| 		catch (LinkageError ex) { | ||||
| 			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException { | ||||
| 	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) | ||||
| 			throws ClassNotFoundException { | ||||
| 
 | ||||
| 		ClassLoader beanClassLoader = getBeanClassLoader(); | ||||
| 		ClassLoader classLoaderToUse = beanClassLoader; | ||||
| 		if (!ObjectUtils.isEmpty(typesToMatch)) { | ||||
|  |  | |||
|  | @ -483,6 +483,7 @@ public abstract class ReflectionUtils { | |||
| 	 * @param clazz the class to introspect | ||||
| 	 * @param mc the callback to invoke for each method | ||||
| 	 * @since 4.2 | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 * @see #doWithMethods | ||||
| 	 */ | ||||
| 	public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) { | ||||
|  | @ -504,6 +505,7 @@ public abstract class ReflectionUtils { | |||
| 	 * twice, unless excluded by a {@link MethodFilter}. | ||||
| 	 * @param clazz the class to introspect | ||||
| 	 * @param mc the callback to invoke for each method | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 * @see #doWithMethods(Class, MethodCallback, MethodFilter) | ||||
| 	 */ | ||||
| 	public static void doWithMethods(Class<?> clazz, MethodCallback mc) { | ||||
|  | @ -518,6 +520,7 @@ public abstract class ReflectionUtils { | |||
| 	 * @param clazz the class to introspect | ||||
| 	 * @param mc the callback to invoke for each method | ||||
| 	 * @param mf the filter that determines the methods to apply the callback to | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 */ | ||||
| 	public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) { | ||||
| 		// Keep backing up the inheritance hierarchy. | ||||
|  | @ -547,6 +550,7 @@ public abstract class ReflectionUtils { | |||
| 	 * Get all declared methods on the leaf class and all superclasses. | ||||
| 	 * Leaf class methods are included first. | ||||
| 	 * @param leafClass the class to introspect | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 */ | ||||
| 	public static Method[] getAllDeclaredMethods(Class<?> leafClass) { | ||||
| 		final List<Method> methods = new ArrayList<Method>(32); | ||||
|  | @ -564,6 +568,7 @@ public abstract class ReflectionUtils { | |||
| 	 * Leaf class methods are included first and while traversing the superclass hierarchy | ||||
| 	 * any methods found with signatures matching a method already included are filtered out. | ||||
| 	 * @param leafClass the class to introspect | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 */ | ||||
| 	public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) { | ||||
| 		final List<Method> methods = new ArrayList<Method>(32); | ||||
|  | @ -604,11 +609,13 @@ public abstract class ReflectionUtils { | |||
| 	 * interfaces, since those are effectively to be treated just like declared methods. | ||||
| 	 * @param clazz the class to introspect | ||||
| 	 * @return the cached array of methods | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 * @see Class#getDeclaredMethods() | ||||
| 	 */ | ||||
| 	private static Method[] getDeclaredMethods(Class<?> clazz) { | ||||
| 		Method[] result = declaredMethodsCache.get(clazz); | ||||
| 		if (result == null) { | ||||
| 			try { | ||||
| 				Method[] declaredMethods = clazz.getDeclaredMethods(); | ||||
| 				List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz); | ||||
| 				if (defaultMethods != null) { | ||||
|  | @ -625,6 +632,11 @@ public abstract class ReflectionUtils { | |||
| 				} | ||||
| 				declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result)); | ||||
| 			} | ||||
| 			catch (Throwable ex) { | ||||
| 				throw new IllegalStateException("Failed to introspect Class [" + clazz + | ||||
| 						"] from ClassLoader [" + clazz.getClassLoader() + "]", ex); | ||||
| 			} | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -649,6 +661,7 @@ public abstract class ReflectionUtils { | |||
| 	 * @param clazz the target class to analyze | ||||
| 	 * @param fc the callback to invoke for each field | ||||
| 	 * @since 4.2 | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 * @see #doWithFields | ||||
| 	 */ | ||||
| 	public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) { | ||||
|  | @ -667,6 +680,7 @@ public abstract class ReflectionUtils { | |||
| 	 * class hierarchy to get all declared fields. | ||||
| 	 * @param clazz the target class to analyze | ||||
| 	 * @param fc the callback to invoke for each field | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 */ | ||||
| 	public static void doWithFields(Class<?> clazz, FieldCallback fc) { | ||||
| 		doWithFields(clazz, fc, null); | ||||
|  | @ -678,6 +692,7 @@ public abstract class ReflectionUtils { | |||
| 	 * @param clazz the target class to analyze | ||||
| 	 * @param fc the callback to invoke for each field | ||||
| 	 * @param ff the filter that determines the fields to apply the callback to | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 */ | ||||
| 	public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff) { | ||||
| 		// Keep backing up the inheritance hierarchy. | ||||
|  | @ -705,14 +720,21 @@ public abstract class ReflectionUtils { | |||
| 	 * in order to avoid the JVM's SecurityManager check and defensive array copying. | ||||
| 	 * @param clazz the class to introspect | ||||
| 	 * @return the cached array of fields | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 * @see Class#getDeclaredFields() | ||||
| 	 */ | ||||
| 	private static Field[] getDeclaredFields(Class<?> clazz) { | ||||
| 		Field[] result = declaredFieldsCache.get(clazz); | ||||
| 		if (result == null) { | ||||
| 			try { | ||||
| 				result = clazz.getDeclaredFields(); | ||||
| 				declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result)); | ||||
| 			} | ||||
| 			catch (Throwable ex) { | ||||
| 				throw new IllegalStateException("Failed to introspect Class [" + clazz + | ||||
| 						"] from ClassLoader [" + clazz.getClassLoader() + "]", ex); | ||||
| 			} | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -720,6 +742,7 @@ public abstract class ReflectionUtils { | |||
| 	 * Given the source object and the destination, which must be the same class | ||||
| 	 * or a subclass, copy all fields, including inherited fields. Designed to | ||||
| 	 * work on objects with public no-arg constructors. | ||||
| 	 * @throws IllegalStateException if introspection fails | ||||
| 	 */ | ||||
| 	public static void shallowCopyFieldState(final Object src, final Object dest) { | ||||
| 		if (src == null) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue