From 4e6148f47b24cb28e64ea2594ecae15d5a1254ae Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 1 May 2023 12:18:33 -0700 Subject: [PATCH] Search for main methods from the bottom of the stack Update `MainMethod` to search from the bottom of the stack rather than the start. Prior to this commit, an incorrect `main` method would be found if more than one `main` was in the stack. Fixes gh-35214 --- .../boot/devtools/restart/MainMethod.java | 6 ++++-- .../boot/devtools/restart/MainMethodTests.java | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java index 5c1c4570fc..a243545378 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -40,7 +40,9 @@ class MainMethod { } private Method getMainMethod(Thread thread) { - for (StackTraceElement element : thread.getStackTrace()) { + StackTraceElement[] stackTrace = thread.getStackTrace(); + for (int i = stackTrace.length - 1; i >= 0; i--) { + StackTraceElement element = stackTrace[i]; if ("main".equals(element.getMethodName())) { Method method = getMainMethod(element); if (method != null) { diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java index 5fe407a427..3995241ab4 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java @@ -56,6 +56,14 @@ class MainMethodTests { assertThat(method.getDeclaringClassName()).isEqualTo(this.actualMain.getDeclaringClass().getName()); } + @Test // gh-35214 + void nestedMainMethod() throws Exception { + MainMethod method = new TestThread(Nested::main).test(); + Method nestedMain = Nested.class.getMethod("main", String[].class); + assertThat(method.getMethod()).isEqualTo(nestedMain); + assertThat(method.getDeclaringClassName()).isEqualTo(nestedMain.getDeclaringClass().getName()); + } + @Test void missingArgsMainMethod() { assertThatIllegalStateException().isThrownBy(() -> new TestThread(MissingArgs::main).test()) @@ -114,6 +122,15 @@ class MainMethodTests { } + public static class Nested { + + public static void main(String... args) { + mainMethod.set(new MainMethod()); + Valid.main(args); + } + + } + public static class MissingArgs { public static void main() {