Update AOT support after RuntimeHints changes

This commit adapts AOT support in various modules after the RuntimeHints
and related deprecation changes.

`MemberCategory.INTROSPECT_*` hints are now removed and
`MemberCategory.*_FIELDS` are  replaced with
`MemberCategory.INVOKE*_FIELDS` when invocation is needed.

Usage of `RuntimeHintsAgent` are also deprecated.

Closes gh-33847
This commit is contained in:
Brian Clozel
2024-11-29 14:44:05 +01:00
parent 0759129c14
commit ba312f6c7c
31 changed files with 81 additions and 111 deletions

View File

@@ -960,7 +960,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
return CodeBlock.of("$L.resolveAndSet($L, $L)", resolver,
REGISTERED_BEAN_PARAMETER, INSTANCE_PARAMETER);
}
hints.reflection().registerMethod(method, ExecutableMode.INTROSPECT);
hints.reflection().registerType(method.getDeclaringClass());
return CodeBlock.of("$L.$L($L.resolve($L))", INSTANCE_PARAMETER,
method.getName(), resolver, REGISTERED_BEAN_PARAMETER);

View File

@@ -40,7 +40,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
import org.springframework.aot.generate.GeneratedMethod;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ResourceHints;
import org.springframework.aot.hint.RuntimeHints;
@@ -812,7 +811,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
Executable userExecutable = instantiationDescriptor.executable();
if (userExecutable instanceof Constructor<?> userConstructor) {
try {
runtimeHints.reflection().registerConstructor(userConstructor, ExecutableMode.INTROSPECT);
runtimeHints.reflection().registerType(userConstructor.getDeclaringClass());
Constructor<?> constructor = this.proxyClass.getConstructor(userExecutable.getParameterTypes());
return new InstantiationDescriptor(constructor);
}

View File

@@ -17,7 +17,6 @@
package org.springframework.context.aot;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
@@ -61,7 +60,7 @@ class KotlinReflectionBeanRegistrationAotProcessor implements BeanRegistrationAo
private void registerHints(Class<?> type, RuntimeHints runtimeHints) {
if (KotlinDetector.isKotlinType(type)) {
runtimeHints.reflection().registerType(type, MemberCategory.INTROSPECT_DECLARED_METHODS);
runtimeHints.reflection().registerType(type);
}
Class<?> superClass = type.getSuperclass();
if (superClass != null) {

View File

@@ -237,7 +237,7 @@ class BeanValidationBeanRegistrationAotProcessor implements BeanRegistrationAotP
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
ReflectionHints hints = generationContext.getRuntimeHints().reflection();
for (Class<?> validatedClass : this.validatedClasses) {
hints.registerType(validatedClass, MemberCategory.DECLARED_FIELDS);
hints.registerType(validatedClass, MemberCategory.INVOKE_DECLARED_FIELDS);
}
for (Class<? extends ConstraintValidator<?, ?>> constraintValidatorClass : this.constraintValidatorClasses) {
hints.registerType(constraintValidatorClass, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);

View File

@@ -534,7 +534,7 @@ class AnnotationConfigApplicationContextTests {
TypeReference cglibType = TypeReference.of(CglibConfiguration.class.getName() + "$$SpringCGLIB$$0");
assertThat(RuntimeHintsPredicates.reflection().onType(cglibType)
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS))
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_FIELDS))
.accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.reflection().onType(CglibConfiguration.class)
.withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS))

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -102,7 +102,7 @@ class ContextAotProcessorTests {
assertThat(directory.resolve(
"source/org/springframework/context/aot/ContextAotProcessorTests_SampleApplication__BeanFactoryRegistrations.java"))
.exists().isRegularFile();
assertThat(directory.resolve("resource/META-INF/native-image/com.example/example/reflect-config.json"))
assertThat(directory.resolve("resource/META-INF/native-image/com.example/example/reachability-metadata.json"))
.exists().isRegularFile();
Path nativeImagePropertiesFile = directory
.resolve("resource/META-INF/native-image/com.example/example/native-image.properties");

View File

@@ -24,7 +24,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.test.agent.EnabledIfRuntimeHintsAgent;
import org.springframework.aot.test.agent.RuntimeHintsInvocations;
import org.springframework.aot.test.agent.RuntimeHintsRecorder;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -46,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Stephane Nicoll
*/
@EnabledIfRuntimeHintsAgent
@SuppressWarnings("removal")
class ApplicationContextAotGeneratorRuntimeHintsTests {
@Test
@@ -100,7 +100,7 @@ class ApplicationContextAotGeneratorRuntimeHintsTests {
TestCompiler.forSystem().with(generationContext).compile(compiled -> {
ApplicationContextInitializer instance = compiled.getInstance(ApplicationContextInitializer.class);
GenericApplicationContext freshContext = new GenericApplicationContext();
RuntimeHintsInvocations recordedInvocations = RuntimeHintsRecorder.record(() -> {
RuntimeHintsInvocations recordedInvocations = org.springframework.aot.test.agent.RuntimeHintsRecorder.record(() -> {
instance.initialize(freshContext);
freshContext.refresh();
freshContext.close();

View File

@@ -79,7 +79,7 @@ class BeanValidationBeanRegistrationAotProcessorTests {
process(MethodParameterLevelConstraint.class);
assertThat(this.generationContext.getRuntimeHints().reflection().typeHints()).hasSize(2);
assertThat(RuntimeHintsPredicates.reflection().onType(MethodParameterLevelConstraint.class)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
assertThat(RuntimeHintsPredicates.reflection().onType(ExistsValidator.class)
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.generationContext.getRuntimeHints());
}
@@ -89,7 +89,7 @@ class BeanValidationBeanRegistrationAotProcessorTests {
process(ConstructorParameterLevelConstraint.class);
assertThat(this.generationContext.getRuntimeHints().reflection().typeHints()).hasSize(2);
assertThat(RuntimeHintsPredicates.reflection().onType(ConstructorParameterLevelConstraint.class)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
assertThat(RuntimeHintsPredicates.reflection().onType(ExistsValidator.class)
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.generationContext.getRuntimeHints());
}
@@ -99,7 +99,7 @@ class BeanValidationBeanRegistrationAotProcessorTests {
process(PropertyLevelConstraint.class);
assertThat(this.generationContext.getRuntimeHints().reflection().typeHints()).hasSize(2);
assertThat(RuntimeHintsPredicates.reflection().onType(PropertyLevelConstraint.class)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
assertThat(RuntimeHintsPredicates.reflection().onType(ExistsValidator.class)
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.generationContext.getRuntimeHints());
}
@@ -109,7 +109,7 @@ class BeanValidationBeanRegistrationAotProcessorTests {
process(GenericTypeLevelConstraint.class);
assertThat(this.generationContext.getRuntimeHints().reflection().typeHints()).hasSize(2);
assertThat(RuntimeHintsPredicates.reflection().onType(GenericTypeLevelConstraint.class)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
assertThat(RuntimeHintsPredicates.reflection().onType(PatternValidator.class)
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.generationContext.getRuntimeHints());
}
@@ -119,9 +119,9 @@ class BeanValidationBeanRegistrationAotProcessorTests {
process(TransitiveGenericTypeLevelConstraint.class);
assertThat(this.generationContext.getRuntimeHints().reflection().typeHints()).hasSize(3);
assertThat(RuntimeHintsPredicates.reflection().onType(TransitiveGenericTypeLevelConstraint.class)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
assertThat(RuntimeHintsPredicates.reflection().onType(Exclude.class)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
assertThat(RuntimeHintsPredicates.reflection().onType(PatternValidator.class)
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.generationContext.getRuntimeHints());
}
@@ -132,7 +132,7 @@ class BeanValidationBeanRegistrationAotProcessorTests {
process(beanClass);
assertThat(this.generationContext.getRuntimeHints().reflection().typeHints()).hasSize(1);
assertThat(RuntimeHintsPredicates.reflection().onType(beanClass)
.withMemberCategory(MemberCategory.DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
}
@Test // gh-33940

View File

@@ -48,16 +48,11 @@ class KotlinReflectionBeanRegistrationAotProcessorTests {
@Test
fun shouldProcessKotlinBean() {
process(SampleKotlinBean::class.java)
assertThat(RuntimeHintsPredicates.reflection().onType(SampleKotlinBean::class.java))
.accepts(generationContext.runtimeHints)
assertThat(
RuntimeHintsPredicates.reflection()
.onType(SampleKotlinBean::class.java)
.withMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS)
).accepts(generationContext.runtimeHints)
assertThat(
RuntimeHintsPredicates.reflection()
.onType(BaseKotlinBean::class.java)
.withMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS)
).accepts(generationContext.runtimeHints)
RuntimeHintsPredicates.reflection().onType(BaseKotlinBean::class.java))
.accepts(generationContext.runtimeHints)
}
@Test
@@ -72,7 +67,6 @@ class KotlinReflectionBeanRegistrationAotProcessorTests {
assertThat(
RuntimeHintsPredicates.reflection()
.onType(OuterBean.NestedBean::class.java)
.withMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS)
.and(RuntimeHintsPredicates.reflection().onType(OuterBean::class.java))
).accepts(generationContext.runtimeHints)
}