diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 59cbd37af6c..4fef9a3817c 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -117,7 +117,13 @@ class ConfigurationClassBeanDefinitionReader { public void loadBeanDefinitions(Set configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); for (ConfigurationClass configClass : configurationModel) { - loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); + try { + loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); + } + catch (Exception ex) { + throw new IllegalStateException("Failed to load bean definitions for configuration class '" + + configClass.getMetadata().getClassName() + "'", ex); + } } } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 353c1586957..c497e8960c5 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -409,23 +409,36 @@ class ConfigurationClassPostProcessorTests { beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class)); beanFactory.setAllowBeanDefinitionOverriding(false); ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); - assertThatExceptionOfType(BeanDefinitionStoreException.class) + + assertThatIllegalStateException() .isThrownBy(() -> pp.postProcessBeanFactory(beanFactory)) - .withMessageContaining("bar") - .withMessageContaining("SingletonBeanConfig") - .withMessageContaining(TestBean.class.getName()); + .withMessage("Failed to load bean definitions for configuration class '%s'", SingletonBeanConfig.class.getName()) + .havingCause() + .isInstanceOf(BeanDefinitionStoreException.class) + .withMessageContainingAll( + "bar", + "SingletonBeanConfig", + TestBean.class.getName() + ); } @Test // gh-25430 void detectAliasOverride() { + Class configClass = SecondConfiguration.class; AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory(); beanFactory.setAllowBeanDefinitionOverriding(false); - context.register(FirstConfiguration.class, SecondConfiguration.class); + context.register(FirstConfiguration.class, configClass); + assertThatIllegalStateException().isThrownBy(context::refresh) - .withMessageContaining("alias 'taskExecutor'") - .withMessageContaining("name 'applicationTaskExecutor'") - .withMessageContaining("bean definition 'taskExecutor'"); + .withMessage("Failed to load bean definitions for configuration class '%s'", configClass.getName()) + .havingCause() + .isExactlyInstanceOf(IllegalStateException.class) + .withMessageContainingAll( + "alias 'taskExecutor'", + "name 'applicationTaskExecutor'", + "bean definition 'taskExecutor'" + ); context.close(); } @@ -1158,8 +1171,11 @@ class ConfigurationClassPostProcessorTests { @Test void testNameClashBetweenConfigurationClassAndBean() { - assertThatExceptionOfType(BeanDefinitionStoreException.class) - .isThrownBy(() -> new AnnotationConfigApplicationContext(MyTestBean.class).getBean("myTestBean", TestBean.class)); + assertThatIllegalStateException() + .isThrownBy(() -> new AnnotationConfigApplicationContext(MyTestBean.class)) + .withMessage("Failed to load bean definitions for configuration class '%s'", MyTestBean.class.getName()) + .havingCause() + .isInstanceOf(BeanDefinitionStoreException.class); } @Test diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java index 0c50d20f0fd..025f4f5d654 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java @@ -60,6 +60,7 @@ import org.springframework.context.support.GenericApplicationContext; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; /** * Miscellaneous system tests covering {@link Bean} naming, aliases, scoping and @@ -222,8 +223,12 @@ class ConfigurationClassProcessingTests { @Test // gh-33330 void configurationWithMethodNameMismatch() { - assertThatExceptionOfType(BeanDefinitionOverrideException.class) - .isThrownBy(() -> initBeanFactory(false, ConfigWithMethodNameMismatch.class)); + Class configClass = ConfigWithMethodNameMismatch.class; + assertThatIllegalStateException() + .isThrownBy(() -> initBeanFactory(false, configClass)) + .withMessage("Failed to load bean definitions for configuration class '%s'", configClass.getName()) + .havingCause() + .isInstanceOf(BeanDefinitionOverrideException.class); } @Test // gh-33920