Remove nulls from description for bean defs with no res description

Previously, if a bean definition had no resource description, the
failure analysis description would state that the been had been
defined in null which was of no use to the user.

This commit updates the failure analysis to omit information about
where the bean was definied when the definition has no resource
description.

Fixes gh-18721
This commit is contained in:
Andy Wilkinson 2019-10-25 14:23:03 +01:00
parent 8d4aeb1a55
commit 65ef03a5bf
2 changed files with 46 additions and 5 deletions

View File

@ -42,11 +42,15 @@ class BeanDefinitionOverrideFailureAnalyzer extends AbstractFailureAnalyzer<Bean
private String getDescription(BeanDefinitionOverrideException ex) {
StringWriter description = new StringWriter();
PrintWriter printer = new PrintWriter(description);
printer.printf(
"The bean '%s', defined in %s, could not be registered. A bean with that "
+ "name has already been defined in %s and overriding is disabled.",
ex.getBeanName(), ex.getBeanDefinition().getResourceDescription(),
ex.getExistingDefinition().getResourceDescription());
printer.printf("The bean '%s'", ex.getBeanName());
if (ex.getBeanDefinition().getResourceDescription() != null) {
printer.printf(", defined in %s,", ex.getBeanDefinition().getResourceDescription());
}
printer.printf(" could not be registered. A bean with that name has already been defined ");
if (ex.getExistingDefinition().getResourceDescription() != null) {
printer.printf("in %s ", ex.getExistingDefinition().getResourceDescription());
}
printer.printf("and overriding is disabled.");
return description.toString();
}

View File

@ -16,10 +16,13 @@
package org.springframework.boot.diagnostics.analyzer;
import java.util.function.Supplier;
import org.junit.Test;
import org.springframework.beans.factory.support.BeanDefinitionOverrideException;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -43,6 +46,18 @@ public class BeanDefinitionOverrideFailureAnalyzerTests {
assertThat(description).contains(FirstConfiguration.class.getName());
}
@Test
public void analyzeBeanDefinitionOverrideExceptionWithDefinitionsWithNoResourceDescription() {
FailureAnalysis analysis = performAnalysis((context) -> {
context.registerBean("testBean", String.class, (Supplier<String>) String::new);
context.registerBean("testBean", String.class, (Supplier<String>) String::new);
});
String description = analysis.getDescription();
assertThat(description)
.isEqualTo("The bean 'testBean' could not be registered. A bean with that name has already"
+ " been defined and overriding is disabled.");
}
private FailureAnalysis performAnalysis(Class<?> configuration) {
BeanDefinitionOverrideException failure = createFailure(configuration);
assertThat(failure).isNotNull();
@ -63,6 +78,28 @@ public class BeanDefinitionOverrideFailureAnalyzerTests {
}
}
private FailureAnalysis performAnalysis(
ApplicationContextInitializer<AnnotationConfigApplicationContext> initializer) {
BeanDefinitionOverrideException failure = createFailure(initializer);
assertThat(failure).isNotNull();
return new BeanDefinitionOverrideFailureAnalyzer().analyze(failure);
}
private BeanDefinitionOverrideException createFailure(
ApplicationContextInitializer<AnnotationConfigApplicationContext> initializer) {
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.setAllowBeanDefinitionOverriding(false);
initializer.initialize(context);
context.refresh();
context.close();
return null;
}
catch (BeanDefinitionOverrideException ex) {
return ex;
}
}
@Configuration
@Import({ FirstConfiguration.class, SecondConfiguration.class })
static class BeanOverrideConfiguration {