Skip to content

Commit

Permalink
Update runtime hints predicates after GraalVM changes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bclozel committed Jan 13, 2025
1 parent 6be8111 commit d28c039
Show file tree
Hide file tree
Showing 24 changed files with 224 additions and 177 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 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.
Expand Down Expand Up @@ -50,7 +50,7 @@ void shouldSkipEmptyClass() {
@Test
void shouldProcessAspect() {
process(TestAspect.class);
assertThat(RuntimeHintsPredicates.reflection().onMethod(TestAspect.class, "alterReturnValue").invoke())
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(TestAspect.class, "alterReturnValue"))
.accepts(this.generationContext.getRuntimeHints());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
Expand Down Expand Up @@ -94,7 +94,7 @@ void contributeWhenPrivateFieldInjectionInjectsUsingReflection() {
RegisteredBean registeredBean = getAndApplyContribution(
PrivateFieldInjectionSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onField(PrivateFieldInjectionSample.class, "environment"))
.onType(PrivateFieldInjectionSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PrivateFieldInjectionSample instance = new PrivateFieldInjectionSample();
Expand All @@ -113,7 +113,7 @@ void contributeWhenPackagePrivateFieldInjectionInjectsUsingConsumer() {
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateFieldInjectionSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onField(PackagePrivateFieldInjectionSample.class, "environment"))
.onType(PackagePrivateFieldInjectionSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateFieldInjectionSample instance = new PackagePrivateFieldInjectionSample();
Expand All @@ -132,7 +132,7 @@ void contributeWhenPackagePrivateFieldInjectionOnParentClassInjectsUsingReflecti
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateFieldInjectionFromParentSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onField(PackagePrivateFieldInjectionSample.class, "environment"))
.onType(PackagePrivateFieldInjectionSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateFieldInjectionFromParentSample instance = new PackagePrivateFieldInjectionFromParentSample();
Expand All @@ -150,7 +150,7 @@ void contributeWhenPrivateMethodInjectionInjectsUsingReflection() {
RegisteredBean registeredBean = getAndApplyContribution(
PrivateMethodInjectionSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PrivateMethodInjectionSample.class, "setTestBean").invoke())
.onMethodInvocation(PrivateMethodInjectionSample.class, "setTestBean"))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PrivateMethodInjectionSample instance = new PrivateMethodInjectionSample();
Expand All @@ -169,7 +169,7 @@ void contributeWhenPackagePrivateMethodInjectionInjectsUsingConsumer() {
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateMethodInjectionSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PackagePrivateMethodInjectionSample.class, "setTestBean").introspect())
.onType(PackagePrivateMethodInjectionSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateMethodInjectionSample instance = new PackagePrivateMethodInjectionSample();
Expand All @@ -188,7 +188,7 @@ void contributeWhenPackagePrivateMethodInjectionOnParentClassInjectsUsingReflect
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateMethodInjectionFromParentSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PackagePrivateMethodInjectionSample.class, "setTestBean"))
.onMethodInvocation(PackagePrivateMethodInjectionSample.class, "setTestBean"))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateMethodInjectionFromParentSample instance = new PackagePrivateMethodInjectionFromParentSample();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
Expand Down Expand Up @@ -568,7 +568,7 @@ private void assertReflectionOnPublisher() {

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 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.
Expand Down Expand Up @@ -79,7 +79,7 @@ void contributeWhenPrivateFieldInjectionInjectsUsingReflection() {
RegisteredBean registeredBean = getAndApplyContribution(
PrivateFieldResourceSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onField(PrivateFieldResourceSample.class, "one"))
.onType(PrivateFieldResourceSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PrivateFieldResourceSample instance = new PrivateFieldResourceSample();
Expand All @@ -98,7 +98,7 @@ void contributeWhenPackagePrivateFieldInjectionInjectsUsingFieldAssignement() {
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateFieldResourceSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onField(PackagePrivateFieldResourceSample.class, "one"))
.onType(PackagePrivateFieldResourceSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateFieldResourceSample instance = new PackagePrivateFieldResourceSample();
Expand All @@ -117,7 +117,7 @@ void contributeWhenPackagePrivateFieldInjectionOnParentClassInjectsUsingReflecti
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateFieldResourceFromParentSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onField(PackagePrivateFieldResourceSample.class, "one"))
.onType(PackagePrivateFieldResourceSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateFieldResourceFromParentSample instance = new PackagePrivateFieldResourceFromParentSample();
Expand All @@ -135,7 +135,7 @@ void contributeWhenPrivateMethodInjectionInjectsUsingReflection() {
RegisteredBean registeredBean = getAndApplyContribution(
PrivateMethodResourceSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PrivateMethodResourceSample.class, "setOne").invoke())
.onMethodInvocation(PrivateMethodResourceSample.class, "setOne"))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PrivateMethodResourceSample instance = new PrivateMethodResourceSample();
Expand All @@ -153,7 +153,7 @@ void contributeWhenPrivateMethodInjectionWithCustomNameInjectsUsingReflection()
RegisteredBean registeredBean = getAndApplyContribution(
PrivateMethodResourceWithCustomNameSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PrivateMethodResourceWithCustomNameSample.class, "setText").invoke())
.onMethodInvocation(PrivateMethodResourceWithCustomNameSample.class, "setText"))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PrivateMethodResourceWithCustomNameSample instance = new PrivateMethodResourceWithCustomNameSample();
Expand All @@ -172,7 +172,7 @@ void contributeWhenPackagePrivateMethodInjectionInjectsUsingMethodInvocation() {
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateMethodResourceSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PackagePrivateMethodResourceSample.class, "setOne").introspect())
.onType(PackagePrivateMethodResourceSample.class))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateMethodResourceSample instance = new PackagePrivateMethodResourceSample();
Expand All @@ -191,7 +191,7 @@ void contributeWhenPackagePrivateMethodInjectionOnParentClassInjectsUsingReflect
RegisteredBean registeredBean = getAndApplyContribution(
PackagePrivateMethodResourceFromParentSample.class);
assertThat(RuntimeHintsPredicates.reflection()
.onMethod(PackagePrivateMethodResourceSample.class, "setOne"))
.onMethodInvocation(PackagePrivateMethodResourceSample.class, "setOne"))
.accepts(this.generationContext.getRuntimeHints());
compile(registeredBean, (postProcessor, compiled) -> {
PackagePrivateMethodResourceFromParentSample instance = new PackagePrivateMethodResourceFromParentSample();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
Expand All @@ -17,7 +17,6 @@
package org.springframework.context.aot;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -565,8 +564,7 @@ void processAheadOfTimeWhenHasCglibProxyWithArgumentsRegisterIntrospectionHintsO
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(ConfigurableCglibConfiguration.class);
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
Constructor<?> userConstructor = ConfigurableCglibConfiguration.class.getDeclaredConstructors()[0];
assertThat(RuntimeHintsPredicates.reflection().onConstructor(userConstructor).introspect())
assertThat(RuntimeHintsPredicates.reflection().onType(ConfigurableCglibConfiguration.class))
.accepts(generationContext.getRuntimeHints());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 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.
Expand All @@ -16,8 +16,6 @@

package org.springframework.context.aot;

import java.lang.reflect.Constructor;

import org.junit.jupiter.api.Test;

import org.springframework.aot.generate.GenerationContext;
Expand Down Expand Up @@ -69,8 +67,7 @@ void shouldProcessAnnotationOnType() {
void shouldProcessAllBeans() throws NoSuchMethodException {
ReflectionHintsPredicates reflection = RuntimeHintsPredicates.reflection();
process(SampleTypeAnnotatedBean.class, SampleConstructorAnnotatedBean.class);
Constructor<?> constructor = SampleConstructorAnnotatedBean.class.getDeclaredConstructor(String.class);
assertThat(reflection.onType(SampleTypeAnnotatedBean.class).and(reflection.onConstructor(constructor)))
assertThat(reflection.onType(SampleTypeAnnotatedBean.class))
.accepts(this.generationContext.getRuntimeHints());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
Expand Down Expand Up @@ -179,8 +179,7 @@ enum InstrumentedMethod {
if (field == null) {
return runtimeHints -> false;
}
return reflection().onType(field.getDeclaringClass())
.or(reflection().onField(field));
return reflection().onType(field.getDeclaringClass());
}),

/**
Expand Down Expand Up @@ -232,25 +231,25 @@ enum InstrumentedMethod {
* {@link Constructor#newInstance(Object...)}.
*/
CONSTRUCTOR_NEWINSTANCE(Constructor.class, "newInstance", HintType.REFLECTION,
invocation -> reflection().onConstructor(invocation.getInstance()).invoke()),
invocation -> reflection().onConstructorInvocation(invocation.getInstance())),

/**
* {@link Method#invoke(Object, Object...)}.
*/
METHOD_INVOKE(Method.class, "invoke", HintType.REFLECTION,
invocation -> reflection().onMethod(invocation.getInstance()).invoke()),
invocation -> reflection().onMethodInvocation(invocation.getInstance())),

/**
* {@link Field#get(Object)}.
*/
FIELD_GET(Field.class, "get", HintType.REFLECTION,
invocation -> reflection().onField(invocation.getInstance())),
invocation -> reflection().onFieldInvocation(invocation.getInstance())),

/**
* {@link Field#set(Object, Object)}.
*/
FIELD_SET(Field.class, "set", HintType.REFLECTION,
invocation -> reflection().onField(invocation.getInstance())),
invocation -> reflection().onFieldInvocation(invocation.getInstance())),


/*
Expand Down
Loading

0 comments on commit d28c039

Please sign in to comment.