From 059054f9da7d86422ae067a3924f248afacb8f01 Mon Sep 17 00:00:00 2001 From: Dmytro Nosan Date: Fri, 7 Nov 2025 13:41:58 +0100 Subject: [PATCH] Devtools Restarter does not work with a parameterless main method Signed-off-by: Dmytro Nosan --- .../boot/devtools/restart/MainMethod.java | 11 +++++- .../devtools/restart/MainMethodTests.java | 37 ++++++++++++------- 2 files changed, 34 insertions(+), 14 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 e18952159180..002f73154340 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 @@ -60,7 +60,7 @@ private boolean isLoaderClass(String className) { private Method getMainMethod(StackTraceElement element) { try { Class elementClass = Class.forName(element.getClassName()); - Method method = elementClass.getDeclaredMethod("main", String[].class); + Method method = getMainMethod(elementClass); if (Modifier.isStatic(method.getModifiers())) { return method; } @@ -71,6 +71,15 @@ private Method getMainMethod(StackTraceElement element) { return null; } + private static Method getMainMethod(Class clazz) throws Exception { + try { + return clazz.getDeclaredMethod("main", String[].class); + } + catch (NoSuchMethodException ex) { + return clazz.getDeclaredMethod("main"); + } + } + /** * Returns the actual main method. * @return the main method 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 d8ced0b9d555..a61575c6a63a 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 @@ -18,7 +18,6 @@ import java.lang.reflect.Method; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.loader.launch.FakeJarLauncher; @@ -37,13 +36,6 @@ class MainMethodTests { private static final ThreadLocal mainMethod = new ThreadLocal<>(); - private Method actualMain; - - @BeforeEach - void setup() throws Exception { - this.actualMain = Valid.class.getMethod("main", String[].class); - } - @Test void threadMustNotBeNull() { assertThatIllegalArgumentException().isThrownBy(() -> new MainMethod(null)) @@ -52,9 +44,10 @@ void threadMustNotBeNull() { @Test void validMainMethod() throws Exception { + Method actualMain = Valid.class.getMethod("main", String[].class); MainMethod method = new TestThread(Valid::main).test(); - assertThat(method.getMethod()).isEqualTo(this.actualMain); - assertThat(method.getDeclaringClassName()).isEqualTo(this.actualMain.getDeclaringClass().getName()); + assertThat(method.getMethod()).isEqualTo(actualMain); + assertThat(method.getDeclaringClassName()).isEqualTo(actualMain.getDeclaringClass().getName()); } @Test // gh-35214 @@ -75,9 +68,19 @@ void viaJarLauncher() throws Exception { } @Test - void missingArgsMainMethod() { - assertThatIllegalStateException().isThrownBy(() -> new TestThread(MissingArgs::main).test()) - .withMessageContaining("Unable to find main method"); + void missingArgsMainMethod() throws Exception { + Method actualMain = MissingArgs.class.getMethod("main"); + MainMethod method = new TestThread(MissingArgs::main).test(); + assertThat(method.getMethod()).isEqualTo(actualMain); + assertThat(method.getDeclaringClassName()).isEqualTo(actualMain.getDeclaringClass().getName()); + } + + @Test + void missingArgsPackagePrivateMainMethod() throws Exception { + Method actualMain = MissingArgsPackagePrivate.class.getDeclaredMethod("main"); + MainMethod method = new TestThread(MissingArgsPackagePrivate::main).test(); + assertThat(method.getMethod()).isEqualTo(actualMain); + assertThat(method.getDeclaringClassName()).isEqualTo(actualMain.getDeclaringClass().getName()); } @Test @@ -149,6 +152,14 @@ public static void main() { } + public static class MissingArgsPackagePrivate { + + static void main() { + mainMethod.set(new MainMethod()); + } + + } + public static class NonStaticMain { void main(String... args) {