Allow Devtools Restarter to work with a parameterless main method

See gh-47987

Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
This commit is contained in:
Dmytro Nosan
2025-11-09 12:10:26 +01:00
committed by Stéphane Nicoll
parent b9216a05e6
commit bf0152e67c
2 changed files with 34 additions and 14 deletions
@@ -60,7 +60,7 @@ class MainMethod {
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 @@ class MainMethod {
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
@@ -18,7 +18,6 @@ package org.springframework.boot.devtools.restart;
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> 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 @@ class MainMethodTests {
@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 @@ class MainMethodTests {
}
@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 @@ class MainMethodTests {
}
public static class MissingArgsPackagePrivate {
static void main() {
mainMethod.set(new MainMethod());
}
}
public static class NonStaticMain {
void main(String... args) {