Skip to content

Commit bfeeb6d

Browse files
committed
Relax requirements for NoUniqueBeanDefinitionFailureAnalyzer
This commit relaxes the requirements for a non-null description to handle a NoUniqueBeanDefinitionException. This can happen if the exception has been thrown programmatically and no injection point is available. This allows the programmatic exception thrown when multiple cache managers are found to be handled properly. Closes gh-13348
1 parent efaebb1 commit bfeeb6d

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -44,15 +44,13 @@ class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnal
4444
@Override
4545
protected FailureAnalysis analyze(Throwable rootFailure, NoUniqueBeanDefinitionException cause,
4646
String description) {
47-
if (description == null) {
48-
return null;
49-
}
5047
String[] beanNames = extractBeanNames(cause);
5148
if (beanNames == null) {
5249
return null;
5350
}
5451
StringBuilder message = new StringBuilder();
55-
message.append(String.format("%s required a single bean, but %d were found:%n", description, beanNames.length));
52+
message.append(String.format("%s required a single bean, but %d were found:%n",
53+
(description != null) ? description : "A component", beanNames.length));
5654
for (String beanName : beanNames) {
5755
buildMessage(message, beanName);
5856
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
import org.junit.jupiter.api.Test;
2020

2121
import org.springframework.beans.factory.BeanCreationException;
22+
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
2223
import org.springframework.beans.factory.ObjectProvider;
2324
import org.springframework.beans.factory.annotation.Autowired;
2425
import org.springframework.boot.diagnostics.FailureAnalysis;
@@ -101,6 +102,21 @@ void failureAnalysisIncludesPossiblyMissingParameterNames() {
101102
assertFoundBeans(failureAnalysis);
102103
}
103104

105+
@Test
106+
void failureAnalysisWithoutInjectionPoints() {
107+
this.context.registerBean("beanOne", TestBean.class);
108+
this.context.register(DuplicateBeansProducer.class);
109+
this.context.refresh();
110+
FailureAnalysis failureAnalysis = analyzeFailure(new NoUniqueBeanDefinitionException(TestBean.class, 3,
111+
"no TestBeanProvider specified and expected single matching TestBean but found 3: beanOne,beanTwo,xmlBean"));
112+
assertThat(failureAnalysis.getDescription())
113+
.startsWith("A component required a single bean, but 3 were found:");
114+
assertThat(failureAnalysis.getDescription()).contains("beanOne: defined in unknown location");
115+
assertThat(failureAnalysis.getDescription())
116+
.contains("beanTwo: defined by method 'beanTwo' in " + DuplicateBeansProducer.class.getName());
117+
assertThat(failureAnalysis.getDescription()).contains("xmlBean: a programmatically registered singleton");
118+
}
119+
104120
private BeanCreationException createFailure(Class<?> consumer) {
105121
this.context.registerBean("beanOne", TestBean.class);
106122
this.context.register(DuplicateBeansProducer.class, consumer);
@@ -114,7 +130,7 @@ private BeanCreationException createFailure(Class<?> consumer) {
114130
return null;
115131
}
116132

117-
private FailureAnalysis analyzeFailure(BeanCreationException failure) {
133+
private FailureAnalysis analyzeFailure(Exception failure) {
118134
return this.analyzer.analyze(failure);
119135
}
120136

0 commit comments

Comments
 (0)