Revisit RuntimeHints API
The `RuntimeHints` API mainly reflects what is needed to write GraalVM reachability metadata. The latest GraalVM version simplified its format. This commit applies relevant simplifications as parts of it are not needed anymore. The new metadata format implies methods, constructors and fields introspection as soon as a reflection hint is registered for a type. As a result, `ExecutableMode.INTROSPECT`, and all `MemberCategory` values except `MemberCategory.INVOKE_*` are being deprecated. They have no replacement, as registering a type hint is enough. In practice, it is enough to replace this: ``` hints.reflection().registerType(MyType.class, MemberCategory.DECLARED_FIELDS); ``` By this: ``` hints.reflection().registerType(MyType.class); ``` As for `MemberCategory.PUBLIC_FIELDS` and `MemberCategory.DECLARED_FIELDS`, values were replaced by `INVOKE_PUBLIC_FIELDS` and `INVOKE_DECLARED_FIELDS` to make their original intent clearer and align with the rest of the API. Note, if you were using those values for reflection only, you can safely remove those hints in favor of a simple type hint. See gh-33847
This commit is contained in:
@@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Phillip Webb
|
||||
* @since 6.0
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class ExecutableHintTests {
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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.
|
||||
@@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class ExecutableModeTests {
|
||||
|
||||
@Test
|
||||
|
||||
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
|
||||
* @author Stephane Nicoll
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class ReflectionHintsTests {
|
||||
|
||||
private final ReflectionHints reflectionHints = new ReflectionHints();
|
||||
|
||||
@@ -117,7 +117,7 @@ class ResourceHintsTests {
|
||||
@Test
|
||||
void registerPatternWithIncludesAndExcludes() {
|
||||
this.resourceHints.registerPattern(resourceHint ->
|
||||
resourceHint.includes("com/example/*.properties").excludes("com/example/to-ignore.properties"));
|
||||
resourceHint.includes("com/example/*.properties"));
|
||||
assertThat(this.resourceHints.resourcePatternHints()).singleElement().satisfies(patternOf(
|
||||
List.of("/", "com", "com/example", "com/example/*.properties"),
|
||||
List.of("com/example/to-ignore.properties")));
|
||||
@@ -198,10 +198,7 @@ class ResourceHintsTests {
|
||||
}
|
||||
|
||||
private Consumer<ResourcePatternHints> patternOf(List<String> includes, List<String> excludes) {
|
||||
return pattern -> {
|
||||
assertThat(pattern.getIncludes()).map(ResourcePatternHint::getPattern).containsExactlyInAnyOrderElementsOf(includes);
|
||||
assertThat(pattern.getExcludes()).map(ResourcePatternHint::getPattern).containsExactlyElementsOf(excludes);
|
||||
};
|
||||
return pattern -> assertThat(pattern.getIncludes()).map(ResourcePatternHint::getPattern).containsExactlyInAnyOrderElementsOf(includes);
|
||||
}
|
||||
|
||||
static class Nested {
|
||||
|
||||
@@ -47,11 +47,9 @@ class RuntimeHintsTests {
|
||||
@Test
|
||||
void resourceHintWithClass() {
|
||||
this.hints.resources().registerType(String.class);
|
||||
assertThat(this.hints.resources().resourcePatternHints()).singleElement().satisfies(resourceHint -> {
|
||||
assertThat(resourceHint.getIncludes()).map(ResourcePatternHint::getPattern)
|
||||
.containsExactlyInAnyOrder("/", "java", "java/lang", "java/lang/String.class");
|
||||
assertThat(resourceHint.getExcludes()).isEmpty();
|
||||
});
|
||||
assertThat(this.hints.resources().resourcePatternHints()).singleElement().satisfies(resourceHint ->
|
||||
assertThat(resourceHint.getIncludes()).map(ResourcePatternHint::getPattern)
|
||||
.containsExactlyInAnyOrder("/", "java", "java/lang", "java/lang/String.class"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class TypeHintTests {
|
||||
|
||||
@Test
|
||||
@@ -169,9 +170,8 @@ class TypeHintTests {
|
||||
void builtWithAppliesMemberCategories() {
|
||||
TypeHint.Builder builder = new TypeHint.Builder(TypeReference.of(String.class));
|
||||
assertThat(builder.build().getMemberCategories()).isEmpty();
|
||||
TypeHint.builtWith(MemberCategory.DECLARED_CLASSES, MemberCategory.DECLARED_FIELDS).accept(builder);
|
||||
assertThat(builder.build().getMemberCategories()).containsExactlyInAnyOrder(MemberCategory.DECLARED_CLASSES,
|
||||
MemberCategory.DECLARED_FIELDS);
|
||||
TypeHint.builtWith(MemberCategory.DECLARED_FIELDS).accept(builder);
|
||||
assertThat(builder.build().getMemberCategories()).containsExactly(MemberCategory.DECLARED_FIELDS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -40,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class ReflectionHintsPredicatesTests {
|
||||
|
||||
private static Constructor<?> privateConstructor;
|
||||
@@ -160,6 +161,12 @@ class ReflectionHintsPredicatesTests {
|
||||
assertPredicateDoesNotMatch(reflection.onConstructor(publicConstructor).introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorIntrospectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorIntrospectionMatchesConstructorHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
@@ -230,22 +237,16 @@ class ReflectionHintsPredicatesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateConstructorIntrospectionMatchesConstructorHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT));
|
||||
void privateConstructorIntrospectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateConstructorIntrospectionDoesNotMatchIntrospectPublicConstructors() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateConstructorIntrospectionDoesNotMatchInvokePublicConstructors() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);
|
||||
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).introspect());
|
||||
void privateConstructorIntrospectionMatchesConstructorHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT));
|
||||
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -303,6 +304,12 @@ class ReflectionHintsPredicatesTests {
|
||||
@Nested
|
||||
class ReflectionOnMethod {
|
||||
|
||||
@Test
|
||||
void methodIntrospectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodIntrospectionMatchesMethodHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
@@ -328,18 +335,6 @@ class ReflectionHintsPredicatesTests {
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodIntrospectionDoesNotMatchIntrospectDeclaredMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodIntrospectionDoesNotMatchInvokeDeclaredMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_DECLARED_METHODS);
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodInvocationDoesNotMatchMethodHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
@@ -379,22 +374,16 @@ class ReflectionHintsPredicatesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateMethodIntrospectionMatchesMethodHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
typeHint.withMethod("privateMethod", Collections.emptyList(), ExecutableMode.INTROSPECT));
|
||||
void privateMethodIntrospectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateMethodIntrospectionDoesNotMatchIntrospectPublicMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_PUBLIC_METHODS);
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateMethodIntrospectionDoesNotMatchInvokePublicMethods() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_METHODS);
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
|
||||
void privateMethodIntrospectionMatchesMethodHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
typeHint.withMethod("privateMethod", Collections.emptyList(), ExecutableMode.INTROSPECT));
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -464,15 +453,15 @@ class ReflectionHintsPredicatesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionMatchesFieldHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
|
||||
void fieldReflectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionDoesNotMatchNonRegisteredFielddHint() {
|
||||
void fieldReflectionMatchesFieldHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField"));
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -482,9 +471,21 @@ class ReflectionHintsPredicatesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldReflectionDoesNotMatchDeclaredFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.DECLARED_FIELDS);
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField"));
|
||||
void fieldInvocationMatchesPublicFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_FIELDS);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").invocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldInvocationDoesNotMatchTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").invocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldReflectionMatchesTypeHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class);
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -493,18 +494,24 @@ class ReflectionHintsPredicatesTests {
|
||||
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldReflectionDoesNotMatchPublicFieldsHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.PUBLIC_FIELDS);
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void privateFieldReflectionMatchesDeclaredFieldsHint() {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void assertPredicateMatches(Predicate<RuntimeHints> predicate) {
|
||||
|
||||
@@ -140,11 +140,8 @@ class FilePatternResourceHintsRegistrarTests {
|
||||
}
|
||||
|
||||
private Consumer<ResourcePatternHints> includes(String... patterns) {
|
||||
return hint -> {
|
||||
assertThat(hint.getIncludes().stream().map(ResourcePatternHint::getPattern))
|
||||
.containsExactlyInAnyOrder(patterns);
|
||||
assertThat(hint.getExcludes()).isEmpty();
|
||||
};
|
||||
return hint -> assertThat(hint.getIncludes().stream().map(ResourcePatternHint::getPattern))
|
||||
.containsExactlyInAnyOrder(patterns);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user