Skip to content

Commit ea3fe95

Browse files
GGGGGHTwilkinsona
authored andcommitted
Use StackWalker to deduce main application class
See gh-31701
1 parent 19030f6 commit ea3fe95

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.LinkedHashSet;
2626
import java.util.List;
2727
import java.util.Map;
28+
import java.util.Objects;
2829
import java.util.Properties;
2930
import java.util.Set;
3031
import java.util.stream.Collectors;
@@ -274,18 +275,10 @@ public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySourc
274275
}
275276

276277
private Class<?> deduceMainApplicationClass() {
277-
try {
278-
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
279-
for (StackTraceElement stackTraceElement : stackTrace) {
280-
if ("main".equals(stackTraceElement.getMethodName())) {
281-
return Class.forName(stackTraceElement.getClassName());
282-
}
283-
}
284-
}
285-
catch (ClassNotFoundException ex) {
286-
// Swallow and continue
287-
}
288-
return null;
278+
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
279+
.walk((s) -> s.filter(e -> Objects.equals(e.getMethodName(), "main")).findFirst()
280+
.map(StackWalker.StackFrame::getDeclaringClass))
281+
.orElse(null);
289282
}
290283

291284
/**

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.LinkedHashSet;
2424
import java.util.List;
2525
import java.util.Map;
26+
import java.util.Objects;
2627
import java.util.Set;
2728
import java.util.concurrent.atomic.AtomicInteger;
2829
import java.util.concurrent.atomic.AtomicReference;
@@ -1314,6 +1315,35 @@ void shouldRegisterHints() {
13141315
.accepts(hints);
13151316
}
13161317

1318+
@Test
1319+
void deduceMainApplicationClass() {
1320+
assertThat(
1321+
Objects.equals(deduceMainApplicationClassByStackWalker(), deduceMainApplicationClassByThrowException()))
1322+
.isTrue();
1323+
}
1324+
1325+
private Class<?> deduceMainApplicationClassByThrowException() {
1326+
try {
1327+
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
1328+
for (StackTraceElement stackTraceElement : stackTrace) {
1329+
if ("main".equals(stackTraceElement.getMethodName())) {
1330+
return Class.forName(stackTraceElement.getClassName());
1331+
}
1332+
}
1333+
}
1334+
catch (ClassNotFoundException ex) {
1335+
// Swallow and continue
1336+
}
1337+
return null;
1338+
}
1339+
1340+
private Class<?> deduceMainApplicationClassByStackWalker() {
1341+
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
1342+
.walk((s) -> s.filter(e -> Objects.equals(e.getMethodName(), "main")).findFirst()
1343+
.map(StackWalker.StackFrame::getDeclaringClass))
1344+
.orElse(null);
1345+
}
1346+
13171347
private <S extends AvailabilityState> ArgumentMatcher<ApplicationEvent> isAvailabilityChangeEventWithState(
13181348
S state) {
13191349
return (argument) -> (argument instanceof AvailabilityChangeEvent<?>)

0 commit comments

Comments
 (0)