diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java index dee8f8eb9fd..26ec867e10a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -44,15 +44,13 @@ class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnal @Override protected FailureAnalysis analyze(Throwable rootFailure, NoUniqueBeanDefinitionException cause, String description) { - if (description == null) { - return null; - } String[] beanNames = extractBeanNames(cause); if (beanNames == null) { return null; } StringBuilder message = new StringBuilder(); - message.append(String.format("%s required a single bean, but %d were found:%n", description, beanNames.length)); + message.append(String.format("%s required a single bean, but %d were found:%n", + (description != null) ? description : "A component", beanNames.length)); for (String beanName : beanNames) { buildMessage(message, beanName); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java index e8600faabe2..e67fc524062 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -19,6 +19,7 @@ package org.springframework.boot.diagnostics.analyzer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.diagnostics.FailureAnalysis; @@ -101,6 +102,21 @@ class NoUniqueBeanDefinitionFailureAnalyzerTests { assertFoundBeans(failureAnalysis); } + @Test + void failureAnalysisWithoutInjectionPoints() { + this.context.registerBean("beanOne", TestBean.class); + this.context.register(DuplicateBeansProducer.class); + this.context.refresh(); + FailureAnalysis failureAnalysis = analyzeFailure(new NoUniqueBeanDefinitionException(TestBean.class, 3, + "no TestBeanProvider specified and expected single matching TestBean but found 3: beanOne,beanTwo,xmlBean")); + assertThat(failureAnalysis.getDescription()) + .startsWith("A component required a single bean, but 3 were found:"); + assertThat(failureAnalysis.getDescription()).contains("beanOne: defined in unknown location"); + assertThat(failureAnalysis.getDescription()) + .contains("beanTwo: defined by method 'beanTwo' in " + DuplicateBeansProducer.class.getName()); + assertThat(failureAnalysis.getDescription()).contains("xmlBean: a programmatically registered singleton"); + } + private BeanCreationException createFailure(Class consumer) { this.context.registerBean("beanOne", TestBean.class); this.context.register(DuplicateBeansProducer.class, consumer); @@ -114,7 +130,7 @@ class NoUniqueBeanDefinitionFailureAnalyzerTests { return null; } - private FailureAnalysis analyzeFailure(BeanCreationException failure) { + private FailureAnalysis analyzeFailure(Exception failure) { return this.analyzer.analyze(failure); }