Skip to content

Commit d28c039

Browse files
committed
Update runtime hints predicates after GraalVM changes
As of gh-33847, method and field introspection is included by default when a type is registered for reflection. Many methods in ReflectionHintsPredicates are now mostly useless as their default behavior checks for introspection. This commit deprecates those methods and promotes instead invocation variants. During the upgrade, developers should replace it for an `onType` check if only reflection is required. If they were checking for invocation, they should use the new 'onXInvocation` method. Closes gh-34239
1 parent 6be8111 commit d28c039

File tree

24 files changed

+224
-177
lines changed

24 files changed

+224
-177
lines changed

spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectJBeanFactoryInitializationAotProcessorTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ void shouldSkipEmptyClass() {
5050
@Test
5151
void shouldProcessAspect() {
5252
process(TestAspect.class);
53-
assertThat(RuntimeHintsPredicates.reflection().onMethod(TestAspect.class, "alterReturnValue").invoke())
53+
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(TestAspect.class, "alterReturnValue"))
5454
.accepts(this.generationContext.getRuntimeHints());
5555
}
5656

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -94,7 +94,7 @@ void contributeWhenPrivateFieldInjectionInjectsUsingReflection() {
9494
RegisteredBean registeredBean = getAndApplyContribution(
9595
PrivateFieldInjectionSample.class);
9696
assertThat(RuntimeHintsPredicates.reflection()
97-
.onField(PrivateFieldInjectionSample.class, "environment"))
97+
.onType(PrivateFieldInjectionSample.class))
9898
.accepts(this.generationContext.getRuntimeHints());
9999
compile(registeredBean, (postProcessor, compiled) -> {
100100
PrivateFieldInjectionSample instance = new PrivateFieldInjectionSample();
@@ -113,7 +113,7 @@ void contributeWhenPackagePrivateFieldInjectionInjectsUsingConsumer() {
113113
RegisteredBean registeredBean = getAndApplyContribution(
114114
PackagePrivateFieldInjectionSample.class);
115115
assertThat(RuntimeHintsPredicates.reflection()
116-
.onField(PackagePrivateFieldInjectionSample.class, "environment"))
116+
.onType(PackagePrivateFieldInjectionSample.class))
117117
.accepts(this.generationContext.getRuntimeHints());
118118
compile(registeredBean, (postProcessor, compiled) -> {
119119
PackagePrivateFieldInjectionSample instance = new PackagePrivateFieldInjectionSample();
@@ -132,7 +132,7 @@ void contributeWhenPackagePrivateFieldInjectionOnParentClassInjectsUsingReflecti
132132
RegisteredBean registeredBean = getAndApplyContribution(
133133
PackagePrivateFieldInjectionFromParentSample.class);
134134
assertThat(RuntimeHintsPredicates.reflection()
135-
.onField(PackagePrivateFieldInjectionSample.class, "environment"))
135+
.onType(PackagePrivateFieldInjectionSample.class))
136136
.accepts(this.generationContext.getRuntimeHints());
137137
compile(registeredBean, (postProcessor, compiled) -> {
138138
PackagePrivateFieldInjectionFromParentSample instance = new PackagePrivateFieldInjectionFromParentSample();
@@ -150,7 +150,7 @@ void contributeWhenPrivateMethodInjectionInjectsUsingReflection() {
150150
RegisteredBean registeredBean = getAndApplyContribution(
151151
PrivateMethodInjectionSample.class);
152152
assertThat(RuntimeHintsPredicates.reflection()
153-
.onMethod(PrivateMethodInjectionSample.class, "setTestBean").invoke())
153+
.onMethodInvocation(PrivateMethodInjectionSample.class, "setTestBean"))
154154
.accepts(this.generationContext.getRuntimeHints());
155155
compile(registeredBean, (postProcessor, compiled) -> {
156156
PrivateMethodInjectionSample instance = new PrivateMethodInjectionSample();
@@ -169,7 +169,7 @@ void contributeWhenPackagePrivateMethodInjectionInjectsUsingConsumer() {
169169
RegisteredBean registeredBean = getAndApplyContribution(
170170
PackagePrivateMethodInjectionSample.class);
171171
assertThat(RuntimeHintsPredicates.reflection()
172-
.onMethod(PackagePrivateMethodInjectionSample.class, "setTestBean").introspect())
172+
.onType(PackagePrivateMethodInjectionSample.class))
173173
.accepts(this.generationContext.getRuntimeHints());
174174
compile(registeredBean, (postProcessor, compiled) -> {
175175
PackagePrivateMethodInjectionSample instance = new PackagePrivateMethodInjectionSample();
@@ -188,7 +188,7 @@ void contributeWhenPackagePrivateMethodInjectionOnParentClassInjectsUsingReflect
188188
RegisteredBean registeredBean = getAndApplyContribution(
189189
PackagePrivateMethodInjectionFromParentSample.class);
190190
assertThat(RuntimeHintsPredicates.reflection()
191-
.onMethod(PackagePrivateMethodInjectionSample.class, "setTestBean"))
191+
.onMethodInvocation(PackagePrivateMethodInjectionSample.class, "setTestBean"))
192192
.accepts(this.generationContext.getRuntimeHints());
193193
compile(registeredBean, (postProcessor, compiled) -> {
194194
PackagePrivateMethodInjectionFromParentSample instance = new PackagePrivateMethodInjectionFromParentSample();

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGeneratorTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -568,7 +568,7 @@ private void assertReflectionOnPublisher() {
568568

569569
private void assertHasMethodInvokeHints(Class<?> beanType, String... methodNames) {
570570
assertThat(methodNames).allMatch(methodName -> RuntimeHintsPredicates.reflection()
571-
.onMethod(beanType, methodName).invoke()
571+
.onMethodInvocation(beanType, methodName)
572572
.test(this.generationContext.getRuntimeHints()));
573573
}
574574

spring-context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanRegistrationAotContributionTests.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ void contributeWhenPrivateFieldInjectionInjectsUsingReflection() {
7979
RegisteredBean registeredBean = getAndApplyContribution(
8080
PrivateFieldResourceSample.class);
8181
assertThat(RuntimeHintsPredicates.reflection()
82-
.onField(PrivateFieldResourceSample.class, "one"))
82+
.onType(PrivateFieldResourceSample.class))
8383
.accepts(this.generationContext.getRuntimeHints());
8484
compile(registeredBean, (postProcessor, compiled) -> {
8585
PrivateFieldResourceSample instance = new PrivateFieldResourceSample();
@@ -98,7 +98,7 @@ void contributeWhenPackagePrivateFieldInjectionInjectsUsingFieldAssignement() {
9898
RegisteredBean registeredBean = getAndApplyContribution(
9999
PackagePrivateFieldResourceSample.class);
100100
assertThat(RuntimeHintsPredicates.reflection()
101-
.onField(PackagePrivateFieldResourceSample.class, "one"))
101+
.onType(PackagePrivateFieldResourceSample.class))
102102
.accepts(this.generationContext.getRuntimeHints());
103103
compile(registeredBean, (postProcessor, compiled) -> {
104104
PackagePrivateFieldResourceSample instance = new PackagePrivateFieldResourceSample();
@@ -117,7 +117,7 @@ void contributeWhenPackagePrivateFieldInjectionOnParentClassInjectsUsingReflecti
117117
RegisteredBean registeredBean = getAndApplyContribution(
118118
PackagePrivateFieldResourceFromParentSample.class);
119119
assertThat(RuntimeHintsPredicates.reflection()
120-
.onField(PackagePrivateFieldResourceSample.class, "one"))
120+
.onType(PackagePrivateFieldResourceSample.class))
121121
.accepts(this.generationContext.getRuntimeHints());
122122
compile(registeredBean, (postProcessor, compiled) -> {
123123
PackagePrivateFieldResourceFromParentSample instance = new PackagePrivateFieldResourceFromParentSample();
@@ -135,7 +135,7 @@ void contributeWhenPrivateMethodInjectionInjectsUsingReflection() {
135135
RegisteredBean registeredBean = getAndApplyContribution(
136136
PrivateMethodResourceSample.class);
137137
assertThat(RuntimeHintsPredicates.reflection()
138-
.onMethod(PrivateMethodResourceSample.class, "setOne").invoke())
138+
.onMethodInvocation(PrivateMethodResourceSample.class, "setOne"))
139139
.accepts(this.generationContext.getRuntimeHints());
140140
compile(registeredBean, (postProcessor, compiled) -> {
141141
PrivateMethodResourceSample instance = new PrivateMethodResourceSample();
@@ -153,7 +153,7 @@ void contributeWhenPrivateMethodInjectionWithCustomNameInjectsUsingReflection()
153153
RegisteredBean registeredBean = getAndApplyContribution(
154154
PrivateMethodResourceWithCustomNameSample.class);
155155
assertThat(RuntimeHintsPredicates.reflection()
156-
.onMethod(PrivateMethodResourceWithCustomNameSample.class, "setText").invoke())
156+
.onMethodInvocation(PrivateMethodResourceWithCustomNameSample.class, "setText"))
157157
.accepts(this.generationContext.getRuntimeHints());
158158
compile(registeredBean, (postProcessor, compiled) -> {
159159
PrivateMethodResourceWithCustomNameSample instance = new PrivateMethodResourceWithCustomNameSample();
@@ -172,7 +172,7 @@ void contributeWhenPackagePrivateMethodInjectionInjectsUsingMethodInvocation() {
172172
RegisteredBean registeredBean = getAndApplyContribution(
173173
PackagePrivateMethodResourceSample.class);
174174
assertThat(RuntimeHintsPredicates.reflection()
175-
.onMethod(PackagePrivateMethodResourceSample.class, "setOne").introspect())
175+
.onType(PackagePrivateMethodResourceSample.class))
176176
.accepts(this.generationContext.getRuntimeHints());
177177
compile(registeredBean, (postProcessor, compiled) -> {
178178
PackagePrivateMethodResourceSample instance = new PackagePrivateMethodResourceSample();
@@ -191,7 +191,7 @@ void contributeWhenPackagePrivateMethodInjectionOnParentClassInjectsUsingReflect
191191
RegisteredBean registeredBean = getAndApplyContribution(
192192
PackagePrivateMethodResourceFromParentSample.class);
193193
assertThat(RuntimeHintsPredicates.reflection()
194-
.onMethod(PackagePrivateMethodResourceSample.class, "setOne"))
194+
.onMethodInvocation(PackagePrivateMethodResourceSample.class, "setOne"))
195195
.accepts(this.generationContext.getRuntimeHints());
196196
compile(registeredBean, (postProcessor, compiled) -> {
197197
PackagePrivateMethodResourceFromParentSample instance = new PackagePrivateMethodResourceFromParentSample();

spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
1717
package org.springframework.context.aot;
1818

1919
import java.io.IOException;
20-
import java.lang.reflect.Constructor;
2120
import java.lang.reflect.Proxy;
2221
import java.util.List;
2322
import java.util.function.BiConsumer;
@@ -565,8 +564,7 @@ void processAheadOfTimeWhenHasCglibProxyWithArgumentsRegisterIntrospectionHintsO
565564
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
566565
applicationContext.registerBean(ConfigurableCglibConfiguration.class);
567566
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
568-
Constructor<?> userConstructor = ConfigurableCglibConfiguration.class.getDeclaredConstructors()[0];
569-
assertThat(RuntimeHintsPredicates.reflection().onConstructor(userConstructor).introspect())
567+
assertThat(RuntimeHintsPredicates.reflection().onType(ConfigurableCglibConfiguration.class))
570568
.accepts(generationContext.getRuntimeHints());
571569
}
572570

spring-context/src/test/java/org/springframework/context/aot/ReflectiveProcessorBeanFactoryInitializationAotProcessorTests.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.context.aot;
1818

19-
import java.lang.reflect.Constructor;
20-
2119
import org.junit.jupiter.api.Test;
2220

2321
import org.springframework.aot.generate.GenerationContext;
@@ -69,8 +67,7 @@ void shouldProcessAnnotationOnType() {
6967
void shouldProcessAllBeans() throws NoSuchMethodException {
7068
ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection();
7169
process(SampleTypeAnnotatedBean.class, SampleConstructorAnnotatedBean.class);
72-
Constructor<?> constructor = SampleConstructorAnnotatedBean.class.getDeclaredConstructor(String.class);
73-
assertThat(reflection.onType(SampleTypeAnnotatedBean.class).and(reflection.onConstructor(constructor)))
70+
assertThat(reflection.onType(SampleTypeAnnotatedBean.class))
7471
.accepts(this.generationContext.getRuntimeHints());
7572
}
7673

spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -179,8 +179,7 @@ enum InstrumentedMethod {
179179
if (field == null) {
180180
return runtimeHints -> false;
181181
}
182-
return reflection().onType(field.getDeclaringClass())
183-
.or(reflection().onField(field));
182+
return reflection().onType(field.getDeclaringClass());
184183
}),
185184

186185
/**
@@ -232,25 +231,25 @@ enum InstrumentedMethod {
232231
* {@link Constructor#newInstance(Object...)}.
233232
*/
234233
CONSTRUCTOR_NEWINSTANCE(Constructor.class, "newInstance", HintType.REFLECTION,
235-
invocation -> reflection().onConstructor(invocation.getInstance()).invoke()),
234+
invocation -> reflection().onConstructorInvocation(invocation.getInstance())),
236235

237236
/**
238237
* {@link Method#invoke(Object, Object...)}.
239238
*/
240239
METHOD_INVOKE(Method.class, "invoke", HintType.REFLECTION,
241-
invocation -> reflection().onMethod(invocation.getInstance()).invoke()),
240+
invocation -> reflection().onMethodInvocation(invocation.getInstance())),
242241

243242
/**
244243
* {@link Field#get(Object)}.
245244
*/
246245
FIELD_GET(Field.class, "get", HintType.REFLECTION,
247-
invocation -> reflection().onField(invocation.getInstance())),
246+
invocation -> reflection().onFieldInvocation(invocation.getInstance())),
248247

249248
/**
250249
* {@link Field#set(Object, Object)}.
251250
*/
252251
FIELD_SET(Field.class, "set", HintType.REFLECTION,
253-
invocation -> reflection().onField(invocation.getInstance())),
252+
invocation -> reflection().onFieldInvocation(invocation.getInstance())),
254253

255254

256255
/*

0 commit comments

Comments
 (0)