Skip to content

Commit b9a09fc

Browse files
committed
Abandon failure analysis if start of cycle cannot be determined
Previously, BeanCurrentlyInCreationFailureAnalyzer would return a FailureAnalysis for any BeanCurrentlyInCreationException even if it could not determine where the cycle begins. This could lead to an inaccurate diagram of the cycle being output. This commit updates BeanCurrentlyInCreationFailureAnalyzer so that it abandons its analysis and returns null if it is unable to determine where the cycle begins. Closes gh-8164
1 parent 9fc90a8 commit b9a09fc

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

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

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2016 the original author or authors.
2+
* Copyright 2012-2017 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.
@@ -39,28 +39,40 @@ class BeanCurrentlyInCreationFailureAnalyzer
3939
@Override
4040
protected FailureAnalysis analyze(Throwable rootFailure,
4141
BeanCurrentlyInCreationException cause) {
42-
List<BeanInCycle> cycle = new ArrayList<BeanInCycle>();
42+
DependencyCycle dependencyCycle = findCycle(rootFailure);
43+
if (dependencyCycle == null) {
44+
return null;
45+
}
46+
return new FailureAnalysis(buildMessage(dependencyCycle), null, cause);
47+
}
48+
49+
private DependencyCycle findCycle(Throwable rootFailure) {
50+
List<BeanInCycle> beansInCycle = new ArrayList<BeanInCycle>();
4351
Throwable candidate = rootFailure;
4452
int cycleStart = -1;
4553
while (candidate != null) {
4654
BeanInCycle beanInCycle = BeanInCycle.get(candidate);
4755
if (beanInCycle != null) {
48-
int index = cycle.indexOf(beanInCycle);
56+
int index = beansInCycle.indexOf(beanInCycle);
4957
if (index == -1) {
50-
cycle.add(beanInCycle);
58+
beansInCycle.add(beanInCycle);
5159
}
5260
cycleStart = (cycleStart == -1 ? index : cycleStart);
5361
}
5462
candidate = candidate.getCause();
5563
}
56-
String message = buildMessage(cycle, cycleStart);
57-
return new FailureAnalysis(message, null, cause);
64+
if (cycleStart == -1) {
65+
return null;
66+
}
67+
return new DependencyCycle(beansInCycle, cycleStart);
5868
}
5969

60-
private String buildMessage(List<BeanInCycle> beansInCycle, int cycleStart) {
70+
private String buildMessage(DependencyCycle dependencyCycle) {
6171
StringBuilder message = new StringBuilder();
6272
message.append(String.format("The dependencies of some of the beans in the "
6373
+ "application context form a cycle:%n%n"));
74+
List<BeanInCycle> beansInCycle = dependencyCycle.getBeansInCycle();
75+
int cycleStart = dependencyCycle.getCycleStart();
6476
for (int i = 0; i < beansInCycle.size(); i++) {
6577
BeanInCycle beanInCycle = beansInCycle.get(i);
6678
if (i == cycleStart) {
@@ -77,6 +89,27 @@ else if (i > 0) {
7789
return message.toString();
7890
}
7991

92+
private static final class DependencyCycle {
93+
94+
private final List<BeanInCycle> beansInCycle;
95+
96+
private final int cycleStart;
97+
98+
private DependencyCycle(List<BeanInCycle> beansInCycle, int cycleStart) {
99+
this.beansInCycle = beansInCycle;
100+
this.cycleStart = cycleStart;
101+
}
102+
103+
public List<BeanInCycle> getBeansInCycle() {
104+
return this.beansInCycle;
105+
}
106+
107+
public int getCycleStart() {
108+
return this.cycleStart;
109+
}
110+
111+
}
112+
80113
private static final class BeanInCycle {
81114

82115
private final String name;

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2016 the original author or authors.
2+
* Copyright 2012-2017 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.
@@ -24,6 +24,7 @@
2424

2525
import org.junit.Test;
2626

27+
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
2728
import org.springframework.beans.factory.annotation.Autowired;
2829
import org.springframework.boot.diagnostics.FailureAnalysis;
2930
import org.springframework.boot.diagnostics.FailureAnalyzer;
@@ -116,6 +117,12 @@ public void cycleReferencedViaOtherBeans() throws IOException {
116117
assertThat(lines.get(11)).isEqualTo("└─────┘");
117118
}
118119

120+
@Test
121+
public void cycleWithAnUnknownStartIsNotAnalyzed() throws IOException {
122+
assertThat(this.analyzer.analyze(new BeanCurrentlyInCreationException("test")))
123+
.isNull();
124+
}
125+
119126
private List<String> readDescriptionLines(FailureAnalysis analysis)
120127
throws IOException {
121128
BufferedReader lineReader = new BufferedReader(

0 commit comments

Comments
 (0)