Fix RuntimeHintsPredicates matching rules
Prior to this commit, the `RuntimeHintsPredicates` would assume that registering introspection or invocation hints for "all declared methods" on a type would also include "all public methods". This is not true, as the Java reflection API itself behaves differently. `getDeclaredMethods()` does not return a superset of `getMethods()`, as the latter can return inherited methods, but not the former. Same reasoning applies to fields. This commit fixes the hints predicates to only match if the correct hint has been registered. Fixes gh-31224
This commit is contained in:
parent
8f130316d2
commit
227049824c
|
@ -408,15 +408,15 @@ class InstrumentedMethodTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void classGetMethodShouldMatchIntrospectDeclaredMethodsHint() {
|
||||
void classGetMethodShouldNotMatchIntrospectDeclaredMethodsHint() {
|
||||
hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod);
|
||||
assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod);
|
||||
}
|
||||
|
||||
@Test
|
||||
void classGetMethodShouldMatchInvokeDeclaredMethodsHint() {
|
||||
void classGetMethodShouldNotMatchInvokeDeclaredMethodsHint() {
|
||||
hints.reflection().registerType(String.class, MemberCategory.INVOKE_DECLARED_METHODS);
|
||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod);
|
||||
assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -544,9 +544,9 @@ class InstrumentedMethodTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void classGetFieldShouldMatchDeclaredFieldsHint() {
|
||||
void classGetFieldShouldNotMatchDeclaredFieldsHint() {
|
||||
hints.reflection().registerType(PublicField.class, MemberCategory.DECLARED_FIELDS);
|
||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETFIELD, this.getPublicField);
|
||||
assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETFIELD, this.getPublicField);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
|
@ -274,19 +274,6 @@ public class ReflectionHintsPredicates {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(RuntimeHints runtimeHints) {
|
||||
return (new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
|
||||
.withAnyMemberCategory(getPublicMemberCategories())
|
||||
.and(hints -> Modifier.isPublic(this.executable.getModifiers())))
|
||||
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass())).withAnyMemberCategory(getDeclaredMemberCategories()))
|
||||
.or(exactMatch()).test(runtimeHints);
|
||||
}
|
||||
|
||||
abstract MemberCategory[] getPublicMemberCategories();
|
||||
|
||||
abstract MemberCategory[] getDeclaredMemberCategories();
|
||||
|
||||
abstract Predicate<RuntimeHints> exactMatch();
|
||||
|
||||
/**
|
||||
|
@ -309,6 +296,14 @@ public class ReflectionHintsPredicates {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean test(RuntimeHints runtimeHints) {
|
||||
return (new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
|
||||
.withAnyMemberCategory(getPublicMemberCategories())
|
||||
.and(hints -> Modifier.isPublic(this.executable.getModifiers())))
|
||||
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass())).withAnyMemberCategory(getDeclaredMemberCategories()))
|
||||
.or(exactMatch()).test(runtimeHints);
|
||||
}
|
||||
|
||||
MemberCategory[] getPublicMemberCategories() {
|
||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||
return new MemberCategory[] { MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS,
|
||||
|
@ -317,7 +312,6 @@ public class ReflectionHintsPredicates {
|
|||
return new MemberCategory[] { MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS };
|
||||
}
|
||||
|
||||
@Override
|
||||
MemberCategory[] getDeclaredMemberCategories() {
|
||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||
return new MemberCategory[] { MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
|
||||
|
@ -344,6 +338,16 @@ public class ReflectionHintsPredicates {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean test(RuntimeHints runtimeHints) {
|
||||
return (new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
|
||||
.withAnyMemberCategory(getPublicMemberCategories())
|
||||
.and(hints -> Modifier.isPublic(this.executable.getModifiers())))
|
||||
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
|
||||
.withAnyMemberCategory(getDeclaredMemberCategories())
|
||||
.and(hints -> !Modifier.isPublic(this.executable.getModifiers())))
|
||||
.or(exactMatch()).test(runtimeHints);
|
||||
}
|
||||
|
||||
MemberCategory[] getPublicMemberCategories() {
|
||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||
return new MemberCategory[] { MemberCategory.INTROSPECT_PUBLIC_METHODS,
|
||||
|
@ -352,7 +356,6 @@ public class ReflectionHintsPredicates {
|
|||
return new MemberCategory[] { MemberCategory.INVOKE_PUBLIC_METHODS };
|
||||
}
|
||||
|
||||
@Override
|
||||
MemberCategory[] getDeclaredMemberCategories() {
|
||||
|
||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||
|
@ -392,8 +395,7 @@ public class ReflectionHintsPredicates {
|
|||
|
||||
private boolean memberCategoryMatch(TypeHint typeHint) {
|
||||
if (Modifier.isPublic(this.field.getModifiers())) {
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.PUBLIC_FIELDS) ||
|
||||
typeHint.getMemberCategories().contains(MemberCategory.DECLARED_FIELDS);
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.PUBLIC_FIELDS);
|
||||
}
|
||||
else {
|
||||
return typeHint.getMemberCategories().contains(MemberCategory.DECLARED_FIELDS);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
|
@ -329,15 +329,15 @@ class ReflectionHintsPredicatesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void methodIntrospectionMatchesIntrospectDeclaredMethods() {
|
||||
void methodIntrospectionDoesNotMatchIntrospectDeclaredMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodIntrospectionMatchesInvokeDeclaredMethods() {
|
||||
void methodIntrospectionDoesNotMatchInvokeDeclaredMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_DECLARED_METHODS);
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -373,9 +373,9 @@ class ReflectionHintsPredicatesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void methodInvocationMatchesInvokeDeclaredMethods() {
|
||||
void methodInvocationDoesNotMatchInvokeDeclaredMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_DECLARED_METHODS);
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").invoke());
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").invoke());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -482,9 +482,9 @@ class ReflectionHintsPredicatesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionMatchesDeclaredFieldsHint() {
|
||||
void fieldReflectionDoesNotMatchDeclaredFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.DECLARED_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue