Browse Source

Merge branch '3.5.x'

Closes gh-48275
pull/48276/head
Stéphane Nicoll 2 months ago
parent
commit
f7f11a4f25
  1. 36
      core/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java
  2. 72
      core/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java

36
core/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
package org.springframework.boot.test.context;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -140,7 +141,14 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao @@ -140,7 +141,14 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
}
ContextLoaderHook hook = new ContextLoaderHook(mode, initializer,
(application) -> configure(mergedConfig, application));
return hook.runMain(() -> ReflectionUtils.invokeMethod(mainMethod, null, new Object[] { args }));
return hook.runMain(() -> {
if (mainMethod.getParameterCount() == 0) {
ReflectionUtils.invokeMethod(mainMethod, null);
}
else {
ReflectionUtils.invokeMethod(mainMethod, null, new Object[] { args });
}
});
}
SpringApplication application = getSpringApplication();
configure(mergedConfig, application);
@ -177,7 +185,7 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao @@ -177,7 +185,7 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
}
private static @Nullable Method findMainMethod(@Nullable Class<?> type) {
Method mainMethod = (type != null) ? ReflectionUtils.findMethod(type, "main", String[].class) : null;
Method mainMethod = (type != null) ? findMainJavaMethod(type) : null;
if (mainMethod == null && KotlinDetector.isKotlinPresent()) {
try {
Assert.state(type != null, "'type' must not be null");
@ -191,6 +199,30 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao @@ -191,6 +199,30 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
return mainMethod;
}
private static @Nullable Method findMainJavaMethod(Class<?> type) {
try {
Method method = getMainMethod(type);
if (Modifier.isStatic(method.getModifiers())) {
method.setAccessible(true);
return method;
}
}
catch (Exception ex) {
// Ignore
}
return null;
}
private static Method getMainMethod(Class<?> type) throws NoSuchMethodException {
try {
return type.getDeclaredMethod("main", String[].class);
}
catch (NoSuchMethodException ex) {
return type.getDeclaredMethod("main");
}
}
private boolean isSpringBootConfiguration(Class<?> candidate) {
return MergedAnnotations.from(candidate, SearchStrategy.TYPE_HIERARCHY)
.isPresent(SpringBootConfiguration.class);

72
core/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java

@ -25,6 +25,8 @@ import org.jspecify.annotations.Nullable; @@ -25,6 +25,8 @@ import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
@ -199,10 +201,13 @@ class SpringBootContextLoaderTests { @@ -199,10 +201,13 @@ class SpringBootContextLoaderTests {
assertThat(applicationContext.getEnvironment().getActiveProfiles()).isEmpty();
}
@Test
void whenUseMainMethodWhenAvailableAndMainMethod() {
TestContext testContext = new ExposedTestContextManager(UseMainMethodWhenAvailableAndMainMethod.class)
.getExposedTestContext();
@ParameterizedTest
@ValueSource(classes = { UsePublicMainMethodWhenAvailableAndMainMethod.class,
UsePublicParameterlessMainMethodWhenAvailableAndMainMethod.class,
UsePackagePrivateMainMethodWhenAvailableAndMainMethod.class,
UsePackagePrivateParameterlessMainMethodWhenAvailableAndMainMethod.class })
void whenUseMainMethodWhenAvailableAndMainMethod(Class<?> testClass) {
TestContext testContext = new ExposedTestContextManager(testClass).getExposedTestContext();
ApplicationContext applicationContext = testContext.getApplicationContext();
assertThat(applicationContext.getEnvironment().getActiveProfiles()).contains("frommain");
}
@ -264,11 +269,11 @@ class SpringBootContextLoaderTests { @@ -264,11 +269,11 @@ class SpringBootContextLoaderTests {
void whenMainMethodPresentRegisterReflectionHints() throws Exception {
SpringBootContextLoader contextLoader = new SpringBootContextLoader();
MergedContextConfiguration contextConfiguration = BootstrapUtils
.resolveTestContextBootstrapper(UseMainMethodWhenAvailableAndMainMethod.class)
.resolveTestContextBootstrapper(UsePublicMainMethodWhenAvailableAndMainMethod.class)
.buildMergedContextConfiguration();
RuntimeHints runtimeHints = new RuntimeHints();
contextLoader.loadContextForAotProcessing(contextConfiguration, runtimeHints);
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(ConfigWithMain.class, "main"))
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(ConfigWithPublicMain.class, "main"))
.accepts(runtimeHints);
}
@ -371,12 +376,28 @@ class SpringBootContextLoaderTests { @@ -371,12 +376,28 @@ class SpringBootContextLoaderTests {
}
@SpringBootTest(classes = ConfigWithMain.class, useMainMethod = UseMainMethod.WHEN_AVAILABLE)
static class UseMainMethodWhenAvailableAndMainMethod {
@SpringBootTest(classes = ConfigWithPublicMain.class, useMainMethod = UseMainMethod.WHEN_AVAILABLE)
static class UsePublicMainMethodWhenAvailableAndMainMethod {
}
@SpringBootTest(classes = ConfigWithPublicParameterlessMain.class, useMainMethod = UseMainMethod.WHEN_AVAILABLE)
static class UsePublicParameterlessMainMethodWhenAvailableAndMainMethod {
}
@SpringBootTest(classes = ConfigWithMain.class, useMainMethod = UseMainMethod.NEVER)
@SpringBootTest(classes = ConfigWithPackagePrivateMain.class, useMainMethod = UseMainMethod.WHEN_AVAILABLE)
static class UsePackagePrivateMainMethodWhenAvailableAndMainMethod {
}
@SpringBootTest(classes = ConfigWithPackagePrivateParameterlessMain.class,
useMainMethod = UseMainMethod.WHEN_AVAILABLE)
static class UsePackagePrivateParameterlessMainMethodWhenAvailableAndMainMethod {
}
@SpringBootTest(classes = ConfigWithPublicMain.class, useMainMethod = UseMainMethod.NEVER)
static class UseMainMethodNever {
}
@ -392,7 +413,7 @@ class SpringBootContextLoaderTests { @@ -392,7 +413,7 @@ class SpringBootContextLoaderTests {
}
@SpringBootTest(useMainMethod = UseMainMethod.ALWAYS)
@ContextHierarchy({ @ContextConfiguration(classes = ConfigWithMain.class),
@ContextHierarchy({ @ContextConfiguration(classes = ConfigWithPublicMain.class),
@ContextConfiguration(classes = AnotherConfigWithMain.class) })
static class UseMainMethodWithContextHierarchy {
@ -423,10 +444,37 @@ class SpringBootContextLoaderTests { @@ -423,10 +444,37 @@ class SpringBootContextLoaderTests {
}
@SpringBootConfiguration(proxyBeanMethods = false)
public static class ConfigWithMain {
public static class ConfigWithPublicMain {
public static void main(String[] args) {
new SpringApplication(ConfigWithMain.class).run("--spring.profiles.active=frommain");
new SpringApplication(ConfigWithPublicMain.class).run("--spring.profiles.active=frommain");
}
}
@SpringBootConfiguration(proxyBeanMethods = false)
public static class ConfigWithPublicParameterlessMain {
public static void main() {
new SpringApplication(ConfigWithPublicMain.class).run("--spring.profiles.active=frommain");
}
}
@SpringBootConfiguration(proxyBeanMethods = false)
public static class ConfigWithPackagePrivateMain {
static void main(String[] args) {
new SpringApplication(ConfigWithPublicMain.class).run("--spring.profiles.active=frommain");
}
}
@SpringBootConfiguration(proxyBeanMethods = false)
public static class ConfigWithPackagePrivateParameterlessMain {
static void main() {
new SpringApplication(ConfigWithPublicMain.class).run("--spring.profiles.active=frommain");
}
}

Loading…
Cancel
Save