Fix hints and predicates for Field reflective access
This commit revisits the arrangement for Field hints after changes made in gh-34239. Closes gh-34294
This commit is contained in:
@@ -74,7 +74,7 @@ class AspectJAdvisorBeanRegistrationAotProcessor implements BeanRegistrationAotP
|
||||
|
||||
@Override
|
||||
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
|
||||
generationContext.getRuntimeHints().reflection().registerType(this.beanClass, MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
generationContext.getRuntimeHints().reflection().registerType(this.beanClass, MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class AspectJAdvisorBeanRegistrationAotProcessorTests {
|
||||
@Test
|
||||
void shouldProcessAspectJClass() {
|
||||
process(AspectJClass.class);
|
||||
assertThat(reflection().onType(AspectJClass.class).withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS))
|
||||
assertThat(reflection().onType(AspectJClass.class).withMemberCategory(MemberCategory.ACCESS_DECLARED_FIELDS))
|
||||
.accepts(this.runtimeHints);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,10 +253,10 @@ class BeanDefinitionPropertiesCodeGenerator {
|
||||
// ReflectionUtils#findField searches recursively in the type hierarchy
|
||||
Class<?> searchType = beanDefinition.getTargetType();
|
||||
while (searchType != null && searchType != writeMethod.getDeclaringClass()) {
|
||||
this.hints.reflection().registerType(searchType, MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
this.hints.reflection().registerType(searchType, MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
searchType = searchType.getSuperclass();
|
||||
}
|
||||
this.hints.reflection().registerType(writeMethod.getDeclaringClass(), MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
this.hints.reflection().registerType(writeMethod.getDeclaringClass(), MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
}
|
||||
|
||||
private void addQualifiers(CodeBlock.Builder code, RootBeanDefinition beanDefinition) {
|
||||
|
||||
@@ -574,7 +574,7 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
||||
|
||||
private void assertHasDeclaredFieldsHint(Class<?> beanType) {
|
||||
assertThat(RuntimeHintsPredicates.reflection()
|
||||
.onType(beanType).withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS))
|
||||
.onType(beanType).withMemberCategory(MemberCategory.ACCESS_DECLARED_FIELDS))
|
||||
.accepts(this.generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,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.INVOKE_DECLARED_FIELDS);
|
||||
hints.registerType(validatedClass, MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
}
|
||||
for (Class<? extends ConstraintValidator<?, ?>> constraintValidatorClass : this.constraintValidatorClasses) {
|
||||
hints.registerType(constraintValidatorClass, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
|
||||
@@ -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.INVOKE_DECLARED_FIELDS))
|
||||
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS))
|
||||
.accepts(runtimeHints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(CglibConfiguration.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS))
|
||||
|
||||
@@ -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.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_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.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_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.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_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.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_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.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Exclude.class)
|
||||
.withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_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.INVOKE_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
.withMemberCategory(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(this.generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
@Test // gh-33940
|
||||
|
||||
@@ -243,13 +243,13 @@ enum InstrumentedMethod {
|
||||
* {@link Field#get(Object)}.
|
||||
*/
|
||||
FIELD_GET(Field.class, "get", HintType.REFLECTION,
|
||||
invocation -> reflection().onFieldInvocation(invocation.getInstance())),
|
||||
invocation -> reflection().onFieldAccess(invocation.getInstance())),
|
||||
|
||||
/**
|
||||
* {@link Field#set(Object, Object)}.
|
||||
*/
|
||||
FIELD_SET(Field.class, "set", HintType.REFLECTION,
|
||||
invocation -> reflection().onFieldInvocation(invocation.getInstance())),
|
||||
invocation -> reflection().onFieldAccess(invocation.getInstance())),
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -100,7 +100,7 @@ public class BindingReflectionHintsRegistrar {
|
||||
typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS);
|
||||
}
|
||||
typeHint.withMembers(MemberCategory.INVOKE_DECLARED_FIELDS,
|
||||
typeHint.withMembers(MemberCategory.ACCESS_DECLARED_FIELDS,
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
for (Method method : clazz.getMethods()) {
|
||||
String methodName = method.getName();
|
||||
|
||||
@@ -33,7 +33,7 @@ public enum MemberCategory {
|
||||
|
||||
/**
|
||||
* A category that represents reflective field access on public {@linkplain Field fields}.
|
||||
* @deprecated in favor of @link #INVOKE_PUBLIC_FIELDS} with similar semantics.
|
||||
* @deprecated in favor of {@link #ACCESS_PUBLIC_FIELDS} with similar semantics.
|
||||
* @see Field#get(Object)
|
||||
* @see Field#set(Object, Object)
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ public enum MemberCategory {
|
||||
* A category that represents reflective field access on
|
||||
* {@linkplain Class#getDeclaredFields() declared fields}: all fields defined by the
|
||||
* class but not inherited fields.
|
||||
* @deprecated in favor of @link #INVOKE_DECLARED_FIELDS} with similar semantics.
|
||||
* @deprecated in favor of {@link #ACCESS_DECLARED_FIELDS} with similar semantics.
|
||||
* @see Class#getDeclaredFields()
|
||||
* @see Field#get(Object)
|
||||
* @see Field#set(Object, Object)
|
||||
@@ -53,20 +53,23 @@ public enum MemberCategory {
|
||||
DECLARED_FIELDS,
|
||||
|
||||
/**
|
||||
* A category that represents getting/setting values on public {@linkplain Field fields}.
|
||||
* A category that represents reflective field access on public {@linkplain Field fields}..
|
||||
* @see Field#get(Object)
|
||||
* @see Field#set(Object, Object)
|
||||
* @since 7.0
|
||||
*/
|
||||
INVOKE_PUBLIC_FIELDS,
|
||||
ACCESS_PUBLIC_FIELDS,
|
||||
|
||||
/**
|
||||
* A category that represents getting/setting values on declared {@linkplain Field fields}.
|
||||
* A category that represents reflective field access on
|
||||
* {@linkplain Class#getDeclaredFields() declared fields}: all fields defined by the
|
||||
* class but not inherited fields.
|
||||
* @see Class#getDeclaredFields()
|
||||
* @see Field#get(Object)
|
||||
* @see Field#set(Object, Object)
|
||||
* @since 7.0
|
||||
*/
|
||||
INVOKE_DECLARED_FIELDS,
|
||||
ACCESS_DECLARED_FIELDS,
|
||||
|
||||
/**
|
||||
* A category that defines public {@linkplain Constructor constructors} can
|
||||
|
||||
@@ -212,19 +212,29 @@ public class ReflectionHintsPredicates {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a predicate that checks whether a reflection hint is registered for the field that matches the given selector.
|
||||
* Return a predicate that checks whether a reflective field access hint is registered for the field.
|
||||
* This looks up a field on the given type with the expected name, if present.
|
||||
* By default, unsafe or write access is not considered.
|
||||
* <p>The returned type exposes additional methods that refine the predicate behavior.
|
||||
* @param type the type holding the field
|
||||
* @param fieldName the field name
|
||||
* @return the {@link RuntimeHints} predicate
|
||||
* @throws IllegalArgumentException if a field cannot be found with the given name.
|
||||
* @deprecated since 7.0 in favor of {@link #onFieldInvocation(Class, String)}
|
||||
* or {@link #onType(Class)}.
|
||||
* @deprecated since 7.0 in favor of {@link #onFieldAccess(Class, String)} with similar semantics.
|
||||
*/
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
public FieldHintPredicate onField(Class<?> type, String fieldName) {
|
||||
public Predicate<RuntimeHints> onField(Class<?> type, String fieldName) {
|
||||
return onFieldAccess(type, fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a predicate that checks whether a reflective field access hint is registered for the field.
|
||||
* This looks up a field on the given type with the expected name, if present.
|
||||
* @param type the type holding the field
|
||||
* @param fieldName the field name
|
||||
* @return the {@link RuntimeHints} predicate
|
||||
* @throws IllegalArgumentException if a field cannot be found with the given name.
|
||||
* @since 7.0
|
||||
*/
|
||||
public Predicate<RuntimeHints> onFieldAccess(Class<?> type, String fieldName) {
|
||||
Assert.notNull(type, "'type' must not be null");
|
||||
Assert.hasText(fieldName, "'fieldName' must not be empty");
|
||||
Field field = ReflectionUtils.findField(type, fieldName);
|
||||
@@ -235,46 +245,22 @@ public class ReflectionHintsPredicates {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a predicate that checks whether an invocation hint is registered for the field that matches the given selector.
|
||||
* Return a predicate that checks whether a reflective field access hint is registered for the field.
|
||||
* This looks up a field on the given type with the expected name, if present.
|
||||
* @param type the type holding the field
|
||||
* @param fieldName the field name
|
||||
* @return the {@link RuntimeHints} predicate
|
||||
* @throws IllegalArgumentException if a field cannot be found with the given name.
|
||||
* @since 7.0
|
||||
*/
|
||||
public Predicate<RuntimeHints> onFieldInvocation(Class<?> type, String fieldName) {
|
||||
Assert.notNull(type, "'type' must not be null");
|
||||
Assert.hasText(fieldName, "'fieldName' must not be empty");
|
||||
Field field = ReflectionUtils.findField(type, fieldName);
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("No field named '%s' on class %s".formatted(fieldName, type.getName()));
|
||||
}
|
||||
return new FieldHintPredicate(field).invocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a predicate that checks whether a reflection hint is registered for the field that matches the given selector.
|
||||
* This looks up a field on the given type with the expected name, if present.
|
||||
* By default, unsafe or write access is not considered.
|
||||
* <p>The returned type exposes additional methods that refine the predicate behavior.
|
||||
* @param className the name of the class holding the field
|
||||
* @param fieldName the field name
|
||||
* @return the {@link RuntimeHints} predicate
|
||||
* @throws ClassNotFoundException if the class cannot be resolved.
|
||||
* @throws IllegalArgumentException if a field cannot be found with the given name.
|
||||
* @deprecated since 7.0 in favor of {@link #onFieldInvocation(String, String)}
|
||||
* or {@link #onType(Class)}.
|
||||
* @deprecated since 7.0 in favor of {@link #onFieldAccess(String, String)} with similar semantics.
|
||||
*/
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
public FieldHintPredicate onField(String className, String fieldName) throws ClassNotFoundException {
|
||||
Assert.hasText(className, "'className' must not be empty");
|
||||
Assert.hasText(fieldName, "'fieldName' must not be empty");
|
||||
return onField(Class.forName(className), fieldName);
|
||||
public Predicate<RuntimeHints> onField(String className, String fieldName) throws ClassNotFoundException {
|
||||
return onFieldAccess(className, fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a predicate that checks whether an invocation hint is registered for the field that matches the given selector.
|
||||
* Return a predicate that checks whether an invocation hint is registered for the field.
|
||||
* This looks up a field on the given type with the expected name, if present.
|
||||
* @param className the name of the class holding the field
|
||||
* @param fieldName the field name
|
||||
@@ -283,23 +269,21 @@ public class ReflectionHintsPredicates {
|
||||
* @throws IllegalArgumentException if a field cannot be found with the given name.
|
||||
* @since 7.0
|
||||
*/
|
||||
public Predicate<RuntimeHints> onFieldInvocation(String className, String fieldName) throws ClassNotFoundException {
|
||||
public Predicate<RuntimeHints> onFieldAccess(String className, String fieldName) throws ClassNotFoundException {
|
||||
Assert.hasText(className, "'className' must not be empty");
|
||||
Assert.hasText(fieldName, "'fieldName' must not be empty");
|
||||
return onField(Class.forName(className), fieldName).invocation();
|
||||
return onFieldAccess(Class.forName(className), fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a predicate that checks whether a reflective field access hint is registered for the given field.
|
||||
* @param field the field
|
||||
* @return the {@link RuntimeHints} predicate
|
||||
* @deprecated since 7.0 in favor of {@link #onFieldInvocation(Field)}
|
||||
* or {@link #onType(Class)}.
|
||||
* @deprecated since 7.0 in favor of {@link #onFieldAccess(Field)} with similar semantics.
|
||||
*/
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
public FieldHintPredicate onField(Field field) {
|
||||
Assert.notNull(field, "'field' must not be null");
|
||||
return new FieldHintPredicate(field);
|
||||
public Predicate<RuntimeHints> onField(Field field) {
|
||||
return onFieldAccess(field);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,9 +292,9 @@ public class ReflectionHintsPredicates {
|
||||
* @return the {@link RuntimeHints} predicate
|
||||
* @since 7.0
|
||||
*/
|
||||
public Predicate<RuntimeHints> onFieldInvocation(Field field) {
|
||||
public Predicate<RuntimeHints> onFieldAccess(Field field) {
|
||||
Assert.notNull(field, "'field' must not be null");
|
||||
return new FieldHintPredicate(field).invocation();
|
||||
return new FieldHintPredicate(field);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,39 +478,34 @@ public class ReflectionHintsPredicates {
|
||||
|
||||
private final Field field;
|
||||
|
||||
private @Nullable ExecutableMode executableMode;
|
||||
|
||||
FieldHintPredicate(Field field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refine the current predicate to only match if an invocation hint is registered for this field.
|
||||
* @return the refined {@link RuntimeHints} predicate
|
||||
* @since 7.0
|
||||
*/
|
||||
public FieldHintPredicate invocation() {
|
||||
this.executableMode = ExecutableMode.INVOKE;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(RuntimeHints runtimeHints) {
|
||||
TypeHint typeHint = runtimeHints.reflection().getTypeHint(this.field.getDeclaringClass());
|
||||
if (typeHint != null) {
|
||||
if (this.executableMode == ExecutableMode.INVOKE) {
|
||||
if (Modifier.isPublic(this.field.getModifiers())) {
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.INVOKE_PUBLIC_FIELDS);
|
||||
}
|
||||
else {
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
if (typeHint == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return memberCategoryMatch(typeHint) || exactMatch(typeHint);
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private boolean memberCategoryMatch(TypeHint typeHint) {
|
||||
if (Modifier.isPublic(this.field.getModifiers())) {
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.ACCESS_PUBLIC_FIELDS)
|
||||
|| typeHint.getMemberCategories().contains(MemberCategory.PUBLIC_FIELDS);
|
||||
}
|
||||
else {
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.ACCESS_DECLARED_FIELDS)
|
||||
|| typeHint.getMemberCategories().contains(MemberCategory.DECLARED_FIELDS);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean exactMatch(TypeHint typeHint) {
|
||||
return typeHint.fields().anyMatch(fieldHint ->
|
||||
this.field.getName().equals(fieldHint.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public abstract class ClassHintUtils {
|
||||
private static final Consumer<TypeHint.Builder> asClassBasedProxy = hint ->
|
||||
hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_METHODS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
|
||||
private static final Consumer<TypeHint.Builder> asProxiedUserClass = hint ->
|
||||
hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS,
|
||||
|
||||
@@ -121,8 +121,8 @@ class ReflectionHintsAttributes {
|
||||
private void handleCategories(Map<String, Object> attributes, Set<MemberCategory> categories) {
|
||||
categories.stream().sorted().forEach(category -> {
|
||||
switch (category) {
|
||||
case INVOKE_PUBLIC_FIELDS, PUBLIC_FIELDS -> attributes.put("allPublicFields", true);
|
||||
case INVOKE_DECLARED_FIELDS, DECLARED_FIELDS -> attributes.put("allDeclaredFields", true);
|
||||
case ACCESS_PUBLIC_FIELDS, PUBLIC_FIELDS -> attributes.put("allPublicFields", true);
|
||||
case ACCESS_DECLARED_FIELDS, DECLARED_FIELDS -> attributes.put("allDeclaredFields", true);
|
||||
case INVOKE_PUBLIC_CONSTRUCTORS ->
|
||||
attributes.put("allPublicConstructors", true);
|
||||
case INVOKE_DECLARED_CONSTRUCTORS ->
|
||||
|
||||
@@ -54,7 +54,7 @@ class BindingReflectionHintsRegistrarTests {
|
||||
.satisfies(typeHint -> {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleEmptyClass.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.methods()).isEmpty();
|
||||
@@ -68,7 +68,7 @@ class BindingReflectionHintsRegistrarTests {
|
||||
typeHint -> {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleEmptyClass.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.methods()).isEmpty();
|
||||
@@ -76,7 +76,7 @@ class BindingReflectionHintsRegistrarTests {
|
||||
typeHint -> {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleExtendingClass.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.methods()).isEmpty();
|
||||
@@ -198,7 +198,7 @@ class BindingReflectionHintsRegistrarTests {
|
||||
typeHint -> {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(ResolvableType.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.methods()).hasSizeGreaterThan(1);
|
||||
@@ -267,7 +267,7 @@ class BindingReflectionHintsRegistrarTests {
|
||||
@Test
|
||||
void registerTypeForJacksonAnnotations() {
|
||||
bindingRegistrar.registerReflectionHints(this.hints.reflection(), SampleClassWithJsonProperty.class);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onFieldInvocation(SampleClassWithJsonProperty.class, "privateField"))
|
||||
assertThat(RuntimeHintsPredicates.reflection().onFieldAccess(SampleClassWithJsonProperty.class, "privateField"))
|
||||
.accepts(this.hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(SampleClassWithJsonProperty.class, "packagePrivateMethod"))
|
||||
.accepts(this.hints);
|
||||
@@ -276,7 +276,7 @@ class BindingReflectionHintsRegistrarTests {
|
||||
@Test
|
||||
void registerTypeForInheritedJacksonAnnotations() {
|
||||
bindingRegistrar.registerReflectionHints(this.hints.reflection(), SampleClassWithInheritedJsonProperty.class);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onFieldInvocation(SampleClassWithJsonProperty.class, "privateField"))
|
||||
assertThat(RuntimeHintsPredicates.reflection().onFieldAccess(SampleClassWithJsonProperty.class, "privateField"))
|
||||
.accepts(this.hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(SampleClassWithJsonProperty.class, "packagePrivateMethod"))
|
||||
.accepts(this.hints);
|
||||
|
||||
@@ -381,68 +381,56 @@ class ReflectionHintsPredicatesTests {
|
||||
|
||||
@Test
|
||||
void shouldFailForUnknownClass() {
|
||||
assertThatThrownBy(() -> reflection.onFieldInvocation("com.example.DoesNotExist", "missingField"))
|
||||
assertThatThrownBy(() -> reflection.onFieldAccess("com.example.DoesNotExist", "missingField"))
|
||||
.isInstanceOf(ClassNotFoundException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionMatchesFieldHint() {
|
||||
void publicFieldAccessMatchesFieldHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionMatchesPublicFieldsHint() {
|
||||
void publicFieldAccessMatchesPublicFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.PUBLIC_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldInvocationMatchesPublicFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").invocation());
|
||||
void publicFieldAccessMatchesAccessPublicFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.ACCESS_PUBLIC_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldInvocationDoesNotMatchTypeHint() {
|
||||
void fieldAccessDoesNotMatchTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").invocation());
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldReflectionMatchesTypeHint() {
|
||||
void privateFieldAccessDoesNotMatchTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldReflectionMatchesFieldHint() {
|
||||
void privateFieldAccessMatchesFieldHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("privateField"));
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldReflectionMatchesDeclaredFieldsHint() {
|
||||
void privateFieldAccessMatchesDeclaredFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.DECLARED_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldInvocationMatchesDeclaredFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField").invocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldInvocationDoesNotMatchTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField").invocation());
|
||||
void privateFieldAccessMatchesAccessDeclaredFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class FileNativeConfigurationWriterTests {
|
||||
ReflectionHints reflectionHints = hints.reflection();
|
||||
reflectionHints.registerType(StringDecoder.class, builder -> builder
|
||||
.onReachableType(String.class)
|
||||
.withMembers(MemberCategory.INVOKE_PUBLIC_FIELDS, MemberCategory.INVOKE_DECLARED_FIELDS,
|
||||
.withMembers(MemberCategory.ACCESS_PUBLIC_FIELDS, MemberCategory.ACCESS_DECLARED_FIELDS,
|
||||
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS)
|
||||
.withField("DEFAULT_CHARSET")
|
||||
|
||||
@@ -82,7 +82,7 @@ class RuntimeHintsWriterTests {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
hints.reflection().registerType(StringDecoder.class, builder -> builder
|
||||
.onReachableType(String.class)
|
||||
.withMembers(MemberCategory.INVOKE_PUBLIC_FIELDS, MemberCategory.INVOKE_DECLARED_FIELDS,
|
||||
.withMembers(MemberCategory.ACCESS_PUBLIC_FIELDS, MemberCategory.ACCESS_DECLARED_FIELDS,
|
||||
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS,
|
||||
MemberCategory.UNSAFE_ALLOCATED)
|
||||
|
||||
@@ -54,7 +54,7 @@ class MessageMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(OutgoingMessage.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -72,7 +72,7 @@ class MessageMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(IncomingMessage.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
|
||||
@@ -85,18 +85,18 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
|
||||
context.registerBean(JpaDomainConfiguration.class);
|
||||
contributeHints(context, hints -> {
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(DriversLicense.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(hints);
|
||||
.withMemberCategories(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Person.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(hints);
|
||||
.withMemberCategories(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(PersonListener.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS))
|
||||
.accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Employee.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(hints);
|
||||
.withMemberCategories(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(Employee.class, "preRemove"))
|
||||
.accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeId.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(hints);
|
||||
.withMemberCategories(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeLocationConverter.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeCategoryConverter.class)
|
||||
@@ -104,7 +104,7 @@ class PersistenceManagedTypesBeanRegistrationAotProcessorTests {
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeKindConverter.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(hints);
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(EmployeeLocation.class)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_FIELDS)).accepts(hints);
|
||||
.withMemberCategories(MemberCategory.ACCESS_DECLARED_FIELDS)).accepts(hints);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class TransactionRuntimeHints implements RuntimeHintsRegistrar {
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
hints.reflection().registerTypes(
|
||||
TypeReference.listOf(Isolation.class, Propagation.class),
|
||||
TypeHint.builtWith(MemberCategory.INVOKE_DECLARED_FIELDS));
|
||||
TypeHint.builtWith(MemberCategory.ACCESS_DECLARED_FIELDS));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Response.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -66,7 +66,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Request.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -84,7 +84,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Request.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -102,7 +102,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Response.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -141,7 +141,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Response.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -167,7 +167,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Request.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
@@ -193,7 +193,7 @@ class ControllerMappingReflectiveProcessorTests {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Request.class));
|
||||
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_FIELDS);
|
||||
MemberCategory.ACCESS_DECLARED_FIELDS);
|
||||
assertThat(typeHint.methods()).satisfiesExactlyInAnyOrder(
|
||||
hint -> assertThat(hint.getName()).isEqualTo("getMessage"),
|
||||
hint -> assertThat(hint.getName()).isEqualTo("setMessage"));
|
||||
|
||||
Reference in New Issue
Block a user