Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
f9b6c1ab
Commit
f9b6c1ab
authored
Oct 10, 2018
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Include more information in NoSuchBeanDefinition failure analysis
Closes gh-13594
parent
9e14fc6b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
28 deletions
+67
-28
NoSuchBeanDefinitionFailureAnalyzer.java
...nostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java
+33
-22
NoSuchBeanDefinitionFailureAnalyzerTests.java
...cs/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java
+34
-6
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java
View file @
f9b6c1ab
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
diagnostics
.
analyzer
;
package
org
.
springframework
.
boot
.
autoconfigure
.
diagnostics
.
analyzer
;
import
java.lang.annotation.Annotation
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
...
@@ -30,6 +31,7 @@ import org.springframework.beans.factory.BeanFactory;
...
@@ -30,6 +31,7 @@ import org.springframework.beans.factory.BeanFactory;
import
org.springframework.beans.factory.BeanFactoryAware
;
import
org.springframework.beans.factory.BeanFactoryAware
;
import
org.springframework.beans.factory.BeanFactoryUtils
;
import
org.springframework.beans.factory.BeanFactoryUtils
;
import
org.springframework.beans.factory.NoSuchBeanDefinitionException
;
import
org.springframework.beans.factory.NoSuchBeanDefinitionException
;
import
org.springframework.beans.factory.UnsatisfiedDependencyException
;
import
org.springframework.beans.factory.annotation.AnnotatedBeanDefinition
;
import
org.springframework.beans.factory.annotation.AnnotatedBeanDefinition
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
...
@@ -89,11 +91,23 @@ class NoSuchBeanDefinitionFailureAnalyzer
...
@@ -89,11 +91,23 @@ class NoSuchBeanDefinitionFailureAnalyzer
message
.
append
(
String
.
format
(
"%s required %s that could not be found.%n"
,
message
.
append
(
String
.
format
(
"%s required %s that could not be found.%n"
,
(
description
!=
null
)
?
description
:
"A component"
,
(
description
!=
null
)
?
description
:
"A component"
,
getBeanDescription
(
cause
)));
getBeanDescription
(
cause
)));
for
(
AutoConfigurationResult
result
:
autoConfigurationResults
)
{
List
<
Annotation
>
injectionAnnotations
=
findInjectionAnnotations
(
rootFailure
);
message
.
append
(
String
.
format
(
"\t- %s%n"
,
result
));
if
(!
injectionAnnotations
.
isEmpty
())
{
message
.
append
(
String
.
format
(
"%nThe injection point has the following annotations:%n"
));
for
(
Annotation
injectionAnnotation
:
injectionAnnotations
)
{
message
.
append
(
String
.
format
(
"\t- %s%n"
,
injectionAnnotation
));
}
}
}
for
(
UserConfigurationResult
result
:
userConfigurationResults
)
{
if
(!
autoConfigurationResults
.
isEmpty
()
||
!
userConfigurationResults
.
isEmpty
())
{
message
.
append
(
String
.
format
(
"\t- %s%n"
,
result
));
message
.
append
(
String
.
format
(
"%nThe following candidates were found but could not be injected:%n"
));
for
(
AutoConfigurationResult
result
:
autoConfigurationResults
)
{
message
.
append
(
String
.
format
(
"\t- %s%n"
,
result
));
}
for
(
UserConfigurationResult
result
:
userConfigurationResults
)
{
message
.
append
(
String
.
format
(
"\t- %s%n"
,
result
));
}
}
}
String
action
=
String
.
format
(
"Consider %s %s in your configuration."
,
String
action
=
String
.
format
(
"Consider %s %s in your configuration."
,
(!
autoConfigurationResults
.
isEmpty
()
(!
autoConfigurationResults
.
isEmpty
()
...
@@ -172,7 +186,7 @@ class NoSuchBeanDefinitionFailureAnalyzer
...
@@ -172,7 +186,7 @@ class NoSuchBeanDefinitionFailureAnalyzer
if
(!
conditionAndOutcome
.
getOutcome
().
isMatch
())
{
if
(!
conditionAndOutcome
.
getOutcome
().
isMatch
())
{
for
(
MethodMetadata
method
:
methods
)
{
for
(
MethodMetadata
method
:
methods
)
{
results
.
add
(
new
AutoConfigurationResult
(
method
,
results
.
add
(
new
AutoConfigurationResult
(
method
,
conditionAndOutcome
.
getOutcome
()
,
source
.
isMethod
()
));
conditionAndOutcome
.
getOutcome
()));
}
}
}
}
}
}
...
@@ -187,11 +201,21 @@ class NoSuchBeanDefinitionFailureAnalyzer
...
@@ -187,11 +201,21 @@ class NoSuchBeanDefinitionFailureAnalyzer
String
message
=
String
.
format
(
"auto-configuration '%s' was excluded"
,
String
message
=
String
.
format
(
"auto-configuration '%s' was excluded"
,
ClassUtils
.
getShortName
(
excludedClass
));
ClassUtils
.
getShortName
(
excludedClass
));
results
.
add
(
new
AutoConfigurationResult
(
method
,
results
.
add
(
new
AutoConfigurationResult
(
method
,
new
ConditionOutcome
(
false
,
message
)
,
false
));
new
ConditionOutcome
(
false
,
message
)));
}
}
}
}
}
}
private
List
<
Annotation
>
findInjectionAnnotations
(
Throwable
failure
)
{
UnsatisfiedDependencyException
unsatisfiedDependencyException
=
findCause
(
failure
,
UnsatisfiedDependencyException
.
class
);
if
(
unsatisfiedDependencyException
==
null
)
{
return
Collections
.
emptyList
();
}
return
Arrays
.
asList
(
unsatisfiedDependencyException
.
getInjectionPoint
().
getAnnotations
());
}
private
class
Source
{
private
class
Source
{
private
final
String
className
;
private
final
String
className
;
...
@@ -212,10 +236,6 @@ class NoSuchBeanDefinitionFailureAnalyzer
...
@@ -212,10 +236,6 @@ class NoSuchBeanDefinitionFailureAnalyzer
return
this
.
methodName
;
return
this
.
methodName
;
}
}
public
boolean
isMethod
()
{
return
this
.
methodName
!=
null
;
}
}
}
private
class
BeanMethods
implements
Iterable
<
MethodMetadata
>
{
private
class
BeanMethods
implements
Iterable
<
MethodMetadata
>
{
...
@@ -303,26 +323,17 @@ class NoSuchBeanDefinitionFailureAnalyzer
...
@@ -303,26 +323,17 @@ class NoSuchBeanDefinitionFailureAnalyzer
private
final
ConditionOutcome
conditionOutcome
;
private
final
ConditionOutcome
conditionOutcome
;
private
final
boolean
methodEvaluated
;
AutoConfigurationResult
(
MethodMetadata
methodMetadata
,
AutoConfigurationResult
(
MethodMetadata
methodMetadata
,
ConditionOutcome
conditionOutcome
,
boolean
methodEvaluated
)
{
ConditionOutcome
conditionOutcome
)
{
this
.
methodMetadata
=
methodMetadata
;
this
.
methodMetadata
=
methodMetadata
;
this
.
conditionOutcome
=
conditionOutcome
;
this
.
conditionOutcome
=
conditionOutcome
;
this
.
methodEvaluated
=
methodEvaluated
;
}
}
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
if
(
this
.
methodEvaluated
)
{
return
String
.
format
(
"Bean method '%s' in '%s' not loaded because %s"
,
return
String
.
format
(
"Bean method '%s' in '%s' not loaded because %s"
,
this
.
methodMetadata
.
getMethodName
(),
ClassUtils
.
getShortName
(
this
.
methodMetadata
.
getDeclaringClassName
()),
this
.
conditionOutcome
.
getMessage
());
}
return
String
.
format
(
"Bean method '%s' not loaded because %s"
,
this
.
methodMetadata
.
getMethodName
(),
this
.
methodMetadata
.
getMethodName
(),
ClassUtils
.
getShortName
(
this
.
methodMetadata
.
getDeclaringClassName
()),
this
.
conditionOutcome
.
getMessage
());
this
.
conditionOutcome
.
getMessage
());
}
}
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java
View file @
f9b6c1ab
...
@@ -27,6 +27,7 @@ import org.springframework.beans.DirectFieldAccessor;
...
@@ -27,6 +27,7 @@ import org.springframework.beans.DirectFieldAccessor;
import
org.springframework.beans.FatalBeanException
;
import
org.springframework.beans.FatalBeanException
;
import
org.springframework.beans.factory.BeanFactory
;
import
org.springframework.beans.factory.BeanFactory
;
import
org.springframework.beans.factory.NoUniqueBeanDefinitionException
;
import
org.springframework.beans.factory.NoUniqueBeanDefinitionException
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.boot.autoconfigure.ImportAutoConfiguration
;
import
org.springframework.boot.autoconfigure.ImportAutoConfiguration
;
import
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport
;
import
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
...
@@ -127,7 +128,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
...
@@ -127,7 +128,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
assertDescriptionConstructorMissingType
(
analysis
,
StringHandler
.
class
,
0
,
assertDescriptionConstructorMissingType
(
analysis
,
StringHandler
.
class
,
0
,
String
.
class
);
String
.
class
);
assertClassDisabled
(
analysis
,
"did not find required class 'com.example.FooBar'"
,
assertClassDisabled
(
analysis
,
"did not find required class 'com.example.FooBar'"
,
"string"
);
"string"
,
ClassUtils
.
getShortName
(
TestTypeClassAutoConfiguration
.
class
)
);
assertActionMissingType
(
analysis
,
String
.
class
);
assertActionMissingType
(
analysis
,
String
.
class
);
}
}
...
@@ -142,7 +143,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
...
@@ -142,7 +143,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
.
getShortName
(
TestPropertyAutoConfiguration
.
class
.
getName
());
.
getShortName
(
TestPropertyAutoConfiguration
.
class
.
getName
());
assertClassDisabled
(
analysis
,
assertClassDisabled
(
analysis
,
String
.
format
(
"auto-configuration '%s' was excluded"
,
configClass
),
String
.
format
(
"auto-configuration '%s' was excluded"
,
configClass
),
"string"
);
"string"
,
ClassUtils
.
getShortName
(
TestPropertyAutoConfiguration
.
class
)
);
assertActionMissingType
(
analysis
,
String
.
class
);
assertActionMissingType
(
analysis
,
String
.
class
);
}
}
...
@@ -156,7 +157,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
...
@@ -156,7 +157,7 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
"did not find property 'spring.string.enabled'"
,
"did not find property 'spring.string.enabled'"
,
TestPropertyAutoConfiguration
.
class
,
"string"
);
TestPropertyAutoConfiguration
.
class
,
"string"
);
assertClassDisabled
(
analysis
,
"did not find required class 'com.example.FooBar'"
,
assertClassDisabled
(
analysis
,
"did not find required class 'com.example.FooBar'"
,
"string"
);
"string"
,
ClassUtils
.
getShortName
(
TestPropertyAutoConfiguration
.
class
)
);
assertActionMissingType
(
analysis
,
String
.
class
);
assertActionMissingType
(
analysis
,
String
.
class
);
}
}
...
@@ -195,6 +196,14 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
...
@@ -195,6 +196,14 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
assertActionMissingType
(
analysis
,
String
.
class
);
assertActionMissingType
(
analysis
,
String
.
class
);
}
}
@Test
public
void
failureAnalysisForUnmatchedQualfier
()
{
FailureAnalysis
analysis
=
analyzeFailure
(
createFailure
(
QualifiedBeanConfiguration
.
class
));
assertThat
(
analysis
.
getDescription
()).
contains
(
"@org.springframework.beans.factory.annotation.Qualifier(value=alpha)"
);
}
private
void
assertDescriptionConstructorMissingType
(
FailureAnalysis
analysis
,
private
void
assertDescriptionConstructorMissingType
(
FailureAnalysis
analysis
,
Class
<?>
component
,
int
index
,
Class
<?>
type
)
{
Class
<?>
component
,
int
index
,
Class
<?>
type
)
{
String
expected
=
String
.
format
(
String
expected
=
String
.
format
(
...
@@ -227,9 +236,9 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
...
@@ -227,9 +236,9 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
}
}
private
void
assertClassDisabled
(
FailureAnalysis
analysis
,
String
description
,
private
void
assertClassDisabled
(
FailureAnalysis
analysis
,
String
description
,
String
methodName
)
{
String
methodName
,
String
className
)
{
String
expected
=
String
.
format
(
"Bean method '%s' not loaded because"
,
String
expected
=
String
.
format
(
"Bean method '%s'
in '%s'
not loaded because"
,
methodName
);
methodName
,
className
);
assertThat
(
analysis
.
getDescription
()).
contains
(
expected
);
assertThat
(
analysis
.
getDescription
()).
contains
(
expected
);
assertThat
(
analysis
.
getDescription
()).
contains
(
description
);
assertThat
(
analysis
.
getDescription
()).
contains
(
description
);
}
}
...
@@ -380,6 +389,25 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
...
@@ -380,6 +389,25 @@ public class NoSuchBeanDefinitionFailureAnalyzerTests {
}
}
@Configuration
public
static
class
QualifiedBeanConfiguration
{
@Bean
public
String
consumer
(
@Qualifier
(
"alpha"
)
Thing
thing
)
{
return
"consumer"
;
}
@Bean
public
Thing
producer
()
{
return
new
Thing
();
}
class
Thing
{
}
}
protected
static
class
StringHandler
{
protected
static
class
StringHandler
{
public
StringHandler
(
String
foo
)
{
public
StringHandler
(
String
foo
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment