Skip to content

Commit f0ebb05

Browse files
committed
Add missing hints for <Application>__EnvironmentPostProcessor
This commit fixes the initialization of the environment in a native image by adding the necessary reflection hints so that the generated EnvironmentPostProcessor is found. Closes gh-48408
1 parent 53d2b30 commit f0ebb05

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListener.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
import org.springframework.aot.AotDetector;
2626
import org.springframework.aot.generate.GeneratedClass;
27+
import org.springframework.aot.generate.GeneratedTypeReference;
2728
import org.springframework.aot.generate.GenerationContext;
29+
import org.springframework.aot.hint.MemberCategory;
2830
import org.springframework.beans.BeanInstantiationException;
2931
import org.springframework.beans.BeanUtils;
3032
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
@@ -59,7 +61,7 @@
5961
*/
6062
public class EnvironmentPostProcessorApplicationListener implements SmartApplicationListener, Ordered {
6163

62-
private static final String AOT_FEATURE_NAME = "EnvironmentPostProcessor";
64+
static final String AOT_FEATURE_NAME = "EnvironmentPostProcessor";
6365

6466
/**
6567
* The default order for the processor.
@@ -234,6 +236,10 @@ public void applyTo(GenerationContext generationContext,
234236
method.addParameter(SpringApplication.class, "application");
235237
method.addCode(generateActiveProfilesInitializeCode());
236238
});
239+
generationContext.getRuntimeHints()
240+
.reflection()
241+
.registerType(GeneratedTypeReference.of(generatedClass.getName()),
242+
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);
237243
}
238244

239245
private CodeBlock generateActiveProfilesInitializeCode() {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListenerTests.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
import org.junit.jupiter.api.io.TempDir;
3636

3737
import org.springframework.aot.AotDetector;
38+
import org.springframework.aot.generate.GenerationContext;
39+
import org.springframework.aot.hint.MemberCategory;
40+
import org.springframework.aot.hint.TypeReference;
41+
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
3842
import org.springframework.aot.test.generate.TestGenerationContext;
3943
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
4044
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -209,6 +213,24 @@ void aotContributionRegistersActiveProfiles() {
209213
});
210214
}
211215

216+
@Test
217+
void aotContributionRegistersReflectionHints() {
218+
GenericApplicationContext applicationContext = new GenericApplicationContext();
219+
ConfigurableEnvironment environment = new StandardEnvironment();
220+
environment.setActiveProfiles("one", "two");
221+
applicationContext.getBeanFactory().registerSingleton("environment", environment);
222+
BeanFactoryInitializationAotContribution aotContribution = new EnvironmentBeanFactoryInitializationAotProcessor()
223+
.processAheadOfTime(applicationContext.getBeanFactory());
224+
assertThat(aotContribution).isNotNull();
225+
GenerationContext generationContext = new TestGenerationContext();
226+
aotContribution.applyTo(generationContext, null);
227+
assertThat(RuntimeHintsPredicates.reflection()
228+
.onType(TypeReference.of(TestGenerationContext.TEST_TARGET + "__"
229+
+ EnvironmentPostProcessorApplicationListener.AOT_FEATURE_NAME))
230+
.withMemberCategory(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS))
231+
.accepts(generationContext.getRuntimeHints());
232+
}
233+
212234
@Test
213235
void shouldUseAotEnvironmentPostProcessor() {
214236
SpringApplication application = new SpringApplication(ExampleAotProcessedApp.class);

0 commit comments

Comments
 (0)