Skip to content

Commit 71362c9

Browse files
committedNov 29, 2024
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
·
v7.0.0-M7v7.0.0-M1
1 parent fec2ed5 commit 71362c9

File tree

12 files changed

+172
-146
lines changed

12 files changed

+172
-146
lines changed
 

‎spring-core/src/main/java/org/springframework/aot/hint/ExecutableMode.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -30,7 +30,10 @@ public enum ExecutableMode {
3030

3131
/**
3232
* Only retrieving the {@link Executable} and its metadata is required.
33+
* @deprecated with no replacement since introspection is included
34+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
3335
*/
36+
@Deprecated(since= "7.0", forRemoval = true)
3437
INTROSPECT,
3538

3639
/**

‎spring-core/src/main/java/org/springframework/aot/hint/MemberCategory.java

Lines changed: 45 additions & 3 deletions
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-2024 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.
@@ -32,32 +32,62 @@
3232
public enum MemberCategory {
3333

3434
/**
35-
* A category that represents public {@linkplain Field fields}.
35+
* A category that represents introspection on public {@linkplain Field fields}.
36+
* @deprecated with no replacement since introspection is included
37+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
38+
* Use {@link #INVOKE_PUBLIC_FIELDS} if getting/setting field values is required.
3639
* @see Class#getFields()
3740
*/
41+
@Deprecated(since = "7.0", forRemoval = true)
3842
PUBLIC_FIELDS,
3943

4044
/**
41-
* A category that represents {@linkplain Class#getDeclaredFields() declared
45+
* A category that represents introspection on {@linkplain Class#getDeclaredFields() declared
4246
* fields}: all fields defined by the class but not inherited fields.
47+
* @deprecated with no replacement since introspection is included
48+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
49+
* Use {@link #INVOKE_DECLARED_FIELDS} if getting/setting field values is required.
4350
* @see Class#getDeclaredFields()
4451
*/
52+
@Deprecated(since = "7.0", forRemoval = true)
4553
DECLARED_FIELDS,
4654

55+
/**
56+
* A category that represents getting/setting values on public {@linkplain Field fields}.
57+
* @see Field#get(Object)
58+
* @see Field#set(Object, Object)
59+
* @since 7.0
60+
*/
61+
INVOKE_PUBLIC_FIELDS,
62+
63+
/**
64+
* A category that represents getting/setting values on declared {@linkplain Field fields}.
65+
* @see Field#get(Object)
66+
* @see Field#set(Object, Object)
67+
* @since 7.0
68+
*/
69+
INVOKE_DECLARED_FIELDS,
70+
4771
/**
4872
* A category that defines public {@linkplain Constructor constructors} can
4973
* be introspected but not invoked.
74+
* @deprecated with no replacement since introspection is included
75+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
5076
* @see Class#getConstructors()
5177
* @see ExecutableMode#INTROSPECT
5278
*/
79+
@Deprecated(since = "7.0", forRemoval = true)
5380
INTROSPECT_PUBLIC_CONSTRUCTORS,
5481

5582
/**
5683
* A category that defines {@linkplain Class#getDeclaredConstructors() all
5784
* constructors} can be introspected but not invoked.
85+
* @deprecated with no replacement since introspection is included
86+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
5887
* @see Class#getDeclaredConstructors()
5988
* @see ExecutableMode#INTROSPECT
6089
*/
90+
@Deprecated(since = "7.0", forRemoval = true)
6191
INTROSPECT_DECLARED_CONSTRUCTORS,
6292

6393
/**
@@ -79,17 +109,23 @@ public enum MemberCategory {
79109
/**
80110
* A category that defines public {@linkplain Method methods}, including
81111
* inherited ones, can be introspected but not invoked.
112+
* @deprecated with no replacement since introspection is added by default
113+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
82114
* @see Class#getMethods()
83115
* @see ExecutableMode#INTROSPECT
84116
*/
117+
@Deprecated(since = "7.0", forRemoval = true)
85118
INTROSPECT_PUBLIC_METHODS,
86119

87120
/**
88121
* A category that defines {@linkplain Class#getDeclaredMethods() all
89122
* methods}, excluding inherited ones, can be introspected but not invoked.
123+
* @deprecated with no replacement since introspection is added by default
124+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
90125
* @see Class#getDeclaredMethods()
91126
* @see ExecutableMode#INTROSPECT
92127
*/
128+
@Deprecated(since = "7.0", forRemoval = true)
93129
INTROSPECT_DECLARED_METHODS,
94130

95131
/**
@@ -114,7 +150,10 @@ public enum MemberCategory {
114150
* <p>Contrary to other categories, this does not register any particular
115151
* reflection for inner classes but rather makes sure they are available
116152
* via a call to {@link Class#getClasses}.
153+
* @deprecated with no replacement since introspection is included
154+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
117155
*/
156+
@Deprecated(since = "7.0", forRemoval = true)
118157
PUBLIC_CLASSES,
119158

120159
/**
@@ -123,7 +162,10 @@ public enum MemberCategory {
123162
* <p>Contrary to other categories, this does not register any particular
124163
* reflection for inner classes but rather makes sure they are available
125164
* via a call to {@link Class#getDeclaredClasses}.
165+
* @deprecated with no replacement since introspection is included
166+
* when {@link ReflectionHints#registerType(Class, MemberCategory...) adding a reflection hint for a type}.
126167
*/
168+
@Deprecated(since = "7.0", forRemoval = true)
127169
DECLARED_CLASSES
128170

129171
}

‎spring-core/src/main/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicates.java

Lines changed: 46 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ public Predicate<RuntimeHints> withAnyMemberCategory(MemberCategory... memberCat
255255
}
256256

257257

258+
@SuppressWarnings("removal")
258259
public abstract static class ExecutableHintPredicate<T extends Executable> implements Predicate<RuntimeHints> {
259260

260261
protected final T executable;
@@ -299,6 +300,7 @@ static boolean includes(ExecutableHint hint, String name,
299300
}
300301

301302

303+
@SuppressWarnings("removal")
302304
public static class ConstructorHintPredicate extends ExecutableHintPredicate<Constructor<?>> {
303305

304306
ConstructorHintPredicate(Constructor<?> constructor) {
@@ -308,28 +310,17 @@ public static class ConstructorHintPredicate extends ExecutableHintPredicate<Con
308310
@Override
309311
public boolean test(RuntimeHints runtimeHints) {
310312
return (new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
311-
.withAnyMemberCategory(getPublicMemberCategories())
312-
.and(hints -> Modifier.isPublic(this.executable.getModifiers())))
313-
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass())).withAnyMemberCategory(getDeclaredMemberCategories()))
313+
.and(hints -> this.executableMode == ExecutableMode.INTROSPECT))
314+
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
315+
.withMemberCategory(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)
316+
.and(hints -> Modifier.isPublic(this.executable.getModifiers()))
317+
.and(hints -> this.executableMode == ExecutableMode.INVOKE))
318+
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
319+
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
320+
.and(hints -> this.executableMode == ExecutableMode.INVOKE))
314321
.or(exactMatch()).test(runtimeHints);
315322
}
316323

317-
MemberCategory[] getPublicMemberCategories() {
318-
if (this.executableMode == ExecutableMode.INTROSPECT) {
319-
return new MemberCategory[] { MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS,
320-
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS };
321-
}
322-
return new MemberCategory[] { MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS };
323-
}
324-
325-
MemberCategory[] getDeclaredMemberCategories() {
326-
if (this.executableMode == ExecutableMode.INTROSPECT) {
327-
return new MemberCategory[] { MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
328-
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS };
329-
}
330-
return new MemberCategory[] { MemberCategory.INVOKE_DECLARED_CONSTRUCTORS };
331-
}
332-
333324
@Override
334325
Predicate<RuntimeHints> exactMatch() {
335326
return hints -> {
@@ -343,6 +334,7 @@ Predicate<RuntimeHints> exactMatch() {
343334
}
344335

345336

337+
@SuppressWarnings("removal")
346338
public static class MethodHintPredicate extends ExecutableHintPredicate<Method> {
347339

348340
MethodHintPredicate(Method method) {
@@ -352,31 +344,18 @@ public static class MethodHintPredicate extends ExecutableHintPredicate<Method>
352344
@Override
353345
public boolean test(RuntimeHints runtimeHints) {
354346
return (new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
355-
.withAnyMemberCategory(getPublicMemberCategories())
356-
.and(hints -> Modifier.isPublic(this.executable.getModifiers())))
357-
.or(new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
358-
.withAnyMemberCategory(getDeclaredMemberCategories())
359-
.and(hints -> !Modifier.isPublic(this.executable.getModifiers())))
347+
.and(hints -> this.executableMode == ExecutableMode.INTROSPECT))
348+
.or((new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
349+
.withMemberCategory(MemberCategory.INVOKE_PUBLIC_METHODS)
350+
.and(hints -> Modifier.isPublic(this.executable.getModifiers()))
351+
.and(hints -> this.executableMode == ExecutableMode.INVOKE)))
352+
.or((new TypeHintPredicate(TypeReference.of(this.executable.getDeclaringClass()))
353+
.withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)
354+
.and(hints -> !Modifier.isPublic(this.executable.getModifiers()))
355+
.and(hints -> this.executableMode == ExecutableMode.INVOKE)))
360356
.or(exactMatch()).test(runtimeHints);
361357
}
362358

363-
MemberCategory[] getPublicMemberCategories() {
364-
if (this.executableMode == ExecutableMode.INTROSPECT) {
365-
return new MemberCategory[] { MemberCategory.INTROSPECT_PUBLIC_METHODS,
366-
MemberCategory.INVOKE_PUBLIC_METHODS };
367-
}
368-
return new MemberCategory[] { MemberCategory.INVOKE_PUBLIC_METHODS };
369-
}
370-
371-
MemberCategory[] getDeclaredMemberCategories() {
372-
373-
if (this.executableMode == ExecutableMode.INTROSPECT) {
374-
return new MemberCategory[] { MemberCategory.INTROSPECT_DECLARED_METHODS,
375-
MemberCategory.INVOKE_DECLARED_METHODS };
376-
}
377-
return new MemberCategory[] { MemberCategory.INVOKE_DECLARED_METHODS };
378-
}
379-
380359
@Override
381360
Predicate<RuntimeHints> exactMatch() {
382361
return hints -> {
@@ -394,31 +373,40 @@ public static class FieldHintPredicate implements Predicate<RuntimeHints> {
394373

395374
private final Field field;
396375

376+
@Nullable
377+
private ExecutableMode executableMode;
378+
397379
FieldHintPredicate(Field field) {
398380
this.field = field;
399381
}
400382

383+
/**
384+
* Refine the current predicate to only match if an invocation hint is registered for this field.
385+
* @return the refined {@link RuntimeHints} predicate
386+
* @since 7.0
387+
*/
388+
public FieldHintPredicate invocation() {
389+
this.executableMode = ExecutableMode.INVOKE;
390+
return this;
391+
}
392+
401393
@Override
402394
public boolean test(RuntimeHints runtimeHints) {
403395
TypeHint typeHint = runtimeHints.reflection().getTypeHint(this.field.getDeclaringClass());
404-
if (typeHint == null) {
405-
return false;
406-
}
407-
return memberCategoryMatch(typeHint) || exactMatch(typeHint);
408-
}
409-
410-
private boolean memberCategoryMatch(TypeHint typeHint) {
411-
if (Modifier.isPublic(this.field.getModifiers())) {
412-
return typeHint.getMemberCategories().contains(MemberCategory.PUBLIC_FIELDS);
396+
if (typeHint != null) {
397+
if (this.executableMode == ExecutableMode.INVOKE) {
398+
if (Modifier.isPublic(this.field.getModifiers())) {
399+
return typeHint.getMemberCategories().contains(MemberCategory.INVOKE_PUBLIC_FIELDS);
400+
}
401+
else {
402+
return typeHint.getMemberCategories().contains(MemberCategory.INVOKE_DECLARED_FIELDS);
403+
}
404+
}
405+
else {
406+
return true;
407+
}
413408
}
414-
else {
415-
return typeHint.getMemberCategories().contains(MemberCategory.DECLARED_FIELDS);
416-
}
417-
}
418-
419-
private boolean exactMatch(TypeHint typeHint) {
420-
return typeHint.fields().anyMatch(fieldHint ->
421-
this.field.getName().equals(fieldHint.getName()));
409+
return false;
422410
}
423411
}
424412

‎spring-core/src/main/java/org/springframework/aot/hint/predicate/ResourceHintsPredicates.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@
1919
import java.util.ArrayList;
2020
import java.util.List;
2121
import java.util.function.Predicate;
22-
import java.util.regex.Pattern;
2322

2423
import org.springframework.aot.hint.ResourceHints;
2524
import org.springframework.aot.hint.ResourcePatternHint;
2625
import org.springframework.aot.hint.RuntimeHints;
2726
import org.springframework.aot.hint.TypeReference;
27+
import org.springframework.util.AntPathMatcher;
2828
import org.springframework.util.Assert;
29-
import org.springframework.util.ConcurrentLruCache;
3029

3130
/**
3231
* Generator of {@link ResourceHints} predicates, testing whether the given hints
@@ -39,7 +38,7 @@
3938
*/
4039
public class ResourceHintsPredicates {
4140

42-
private static final ConcurrentLruCache<ResourcePatternHint, Pattern> CACHED_RESOURCE_PATTERNS = new ConcurrentLruCache<>(32, ResourcePatternHint::toRegex);
41+
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
4342

4443
ResourceHintsPredicates() {
4544
}
@@ -100,26 +99,18 @@ public Predicate<RuntimeHints> forResource(String resourceName) {
10099
return hints -> {
101100
AggregatedResourcePatternHints aggregatedResourcePatternHints = AggregatedResourcePatternHints.of(
102101
hints.resources());
103-
boolean isExcluded = aggregatedResourcePatternHints.excludes().stream().anyMatch(excluded ->
104-
CACHED_RESOURCE_PATTERNS.get(excluded).matcher(resourceNameToUse).matches());
105-
if (isExcluded) {
106-
return false;
107-
}
108102
return aggregatedResourcePatternHints.includes().stream().anyMatch(included ->
109-
CACHED_RESOURCE_PATTERNS.get(included).matcher(resourceNameToUse).matches());
103+
PATH_MATCHER.match(included.getPattern(), resourceNameToUse));
110104
};
111105
}
112106

113-
private record AggregatedResourcePatternHints(List<ResourcePatternHint> includes, List<ResourcePatternHint> excludes) {
107+
private record AggregatedResourcePatternHints(List<ResourcePatternHint> includes) {
114108

115109
static AggregatedResourcePatternHints of(ResourceHints resourceHints) {
116110
List<ResourcePatternHint> includes = new ArrayList<>();
117-
List<ResourcePatternHint> excludes = new ArrayList<>();
118-
resourceHints.resourcePatternHints().forEach(resourcePatternHint -> {
119-
includes.addAll(resourcePatternHint.getIncludes());
120-
excludes.addAll(resourcePatternHint.getExcludes());
121-
});
122-
return new AggregatedResourcePatternHints(includes, excludes);
111+
resourceHints.resourcePatternHints().forEach(resourcePatternHint ->
112+
includes.addAll(resourcePatternHint.getIncludes()));
113+
return new AggregatedResourcePatternHints(includes);
123114
}
124115

125116
}

‎spring-core/src/test/java/org/springframework/aot/hint/ExecutableHintTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* @author Phillip Webb
2929
* @since 6.0
3030
*/
31+
@SuppressWarnings("removal")
3132
class ExecutableHintTests {
3233

3334
@Test

‎spring-core/src/test/java/org/springframework/aot/hint/ExecutableModeTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -25,6 +25,7 @@
2525
*
2626
* @author Stephane Nicoll
2727
*/
28+
@SuppressWarnings("removal")
2829
class ExecutableModeTests {
2930

3031
@Test

‎spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* @author Stephane Nicoll
3838
* @author Sebastien Deleuze
3939
*/
40+
@SuppressWarnings("removal")
4041
class ReflectionHintsTests {
4142

4243
private final ReflectionHints reflectionHints = new ReflectionHints();

‎spring-core/src/test/java/org/springframework/aot/hint/ResourceHintsTests.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void registerPattern() {
117117
@Test
118118
void registerPatternWithIncludesAndExcludes() {
119119
this.resourceHints.registerPattern(resourceHint ->
120-
resourceHint.includes("com/example/*.properties").excludes("com/example/to-ignore.properties"));
120+
resourceHint.includes("com/example/*.properties"));
121121
assertThat(this.resourceHints.resourcePatternHints()).singleElement().satisfies(patternOf(
122122
List.of("/", "com", "com/example", "com/example/*.properties"),
123123
List.of("com/example/to-ignore.properties")));
@@ -198,10 +198,7 @@ private Consumer<ResourceBundleHint> resourceBundle(String baseName) {
198198
}
199199

200200
private Consumer<ResourcePatternHints> patternOf(List<String> includes, List<String> excludes) {
201-
return pattern -> {
202-
assertThat(pattern.getIncludes()).map(ResourcePatternHint::getPattern).containsExactlyInAnyOrderElementsOf(includes);
203-
assertThat(pattern.getExcludes()).map(ResourcePatternHint::getPattern).containsExactlyElementsOf(excludes);
204-
};
201+
return pattern -> assertThat(pattern.getIncludes()).map(ResourcePatternHint::getPattern).containsExactlyInAnyOrderElementsOf(includes);
205202
}
206203

207204
static class Nested {

‎spring-core/src/test/java/org/springframework/aot/hint/RuntimeHintsTests.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,9 @@ void reflectionHintWithClass() {
4747
@Test
4848
void resourceHintWithClass() {
4949
this.hints.resources().registerType(String.class);
50-
assertThat(this.hints.resources().resourcePatternHints()).singleElement().satisfies(resourceHint -> {
51-
assertThat(resourceHint.getIncludes()).map(ResourcePatternHint::getPattern)
52-
.containsExactlyInAnyOrder("/", "java", "java/lang", "java/lang/String.class");
53-
assertThat(resourceHint.getExcludes()).isEmpty();
54-
});
50+
assertThat(this.hints.resources().resourcePatternHints()).singleElement().satisfies(resourceHint ->
51+
assertThat(resourceHint.getIncludes()).map(ResourcePatternHint::getPattern)
52+
.containsExactlyInAnyOrder("/", "java", "java/lang", "java/lang/String.class"));
5553
}
5654

5755
@Test

‎spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
*
3232
* @author Stephane Nicoll
3333
*/
34+
@SuppressWarnings("removal")
3435
class TypeHintTests {
3536

3637
@Test
@@ -169,9 +170,8 @@ void typeHintHasAppropriateToString() {
169170
void builtWithAppliesMemberCategories() {
170171
TypeHint.Builder builder = new TypeHint.Builder(TypeReference.of(String.class));
171172
assertThat(builder.build().getMemberCategories()).isEmpty();
172-
TypeHint.builtWith(MemberCategory.DECLARED_CLASSES, MemberCategory.DECLARED_FIELDS).accept(builder);
173-
assertThat(builder.build().getMemberCategories()).containsExactlyInAnyOrder(MemberCategory.DECLARED_CLASSES,
174-
MemberCategory.DECLARED_FIELDS);
173+
TypeHint.builtWith(MemberCategory.DECLARED_FIELDS).accept(builder);
174+
assertThat(builder.build().getMemberCategories()).containsExactly(MemberCategory.DECLARED_FIELDS);
175175
}
176176

177177
}

‎spring-core/src/test/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicatesTests.java

Lines changed: 56 additions & 49 deletions
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-2024 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.
@@ -40,6 +40,7 @@
4040
*
4141
* @author Brian Clozel
4242
*/
43+
@SuppressWarnings("removal")
4344
class ReflectionHintsPredicatesTests {
4445

4546
private static Constructor<?> privateConstructor;
@@ -160,6 +161,12 @@ void constructorIntrospectionDoesNotMatchMissingHint() {
160161
assertPredicateDoesNotMatch(reflection.onConstructor(publicConstructor).introspect());
161162
}
162163

164+
@Test
165+
void constructorIntrospectionMatchesTypeHint() {
166+
runtimeHints.reflection().registerType(SampleClass.class);
167+
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
168+
}
169+
163170
@Test
164171
void constructorIntrospectionMatchesConstructorHint() {
165172
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
@@ -230,22 +237,16 @@ void constructorInvocationMatchesInvokeDeclaredConstructors() {
230237
}
231238

232239
@Test
233-
void privateConstructorIntrospectionMatchesConstructorHint() {
234-
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
235-
typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT));
240+
void privateConstructorIntrospectionMatchesTypeHint() {
241+
runtimeHints.reflection().registerType(SampleClass.class);
236242
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
237243
}
238244

239245
@Test
240-
void privateConstructorIntrospectionDoesNotMatchIntrospectPublicConstructors() {
241-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
242-
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).introspect());
243-
}
244-
245-
@Test
246-
void privateConstructorIntrospectionDoesNotMatchInvokePublicConstructors() {
247-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);
248-
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).introspect());
246+
void privateConstructorIntrospectionMatchesConstructorHint() {
247+
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
248+
typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT));
249+
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
249250
}
250251

251252
@Test
@@ -303,6 +304,12 @@ void privateConstructorInvocationMatchesInvokeDeclaredConstructors() {
303304
@Nested
304305
class ReflectionOnMethod {
305306

307+
@Test
308+
void methodIntrospectionMatchesTypeHint() {
309+
runtimeHints.reflection().registerType(SampleClass.class);
310+
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
311+
}
312+
306313
@Test
307314
void methodIntrospectionMatchesMethodHint() {
308315
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
@@ -328,18 +335,6 @@ void methodIntrospectionMatchesInvokePublicMethods() {
328335
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
329336
}
330337

331-
@Test
332-
void methodIntrospectionDoesNotMatchIntrospectDeclaredMethods() {
333-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_DECLARED_METHODS);
334-
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
335-
}
336-
337-
@Test
338-
void methodIntrospectionDoesNotMatchInvokeDeclaredMethods() {
339-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_DECLARED_METHODS);
340-
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").introspect());
341-
}
342-
343338
@Test
344339
void methodInvocationDoesNotMatchMethodHint() {
345340
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
@@ -379,22 +374,16 @@ void methodInvocationDoesNotMatchInvokeDeclaredMethods() {
379374
}
380375

381376
@Test
382-
void privateMethodIntrospectionMatchesMethodHint() {
383-
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
384-
typeHint.withMethod("privateMethod", Collections.emptyList(), ExecutableMode.INTROSPECT));
377+
void privateMethodIntrospectionMatchesTypeHint() {
378+
runtimeHints.reflection().registerType(SampleClass.class);
385379
assertPredicateMatches(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
386380
}
387381

388382
@Test
389-
void privateMethodIntrospectionDoesNotMatchIntrospectPublicMethods() {
390-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INTROSPECT_PUBLIC_METHODS);
391-
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
392-
}
393-
394-
@Test
395-
void privateMethodIntrospectionDoesNotMatchInvokePublicMethods() {
396-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_METHODS);
397-
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
383+
void privateMethodIntrospectionMatchesMethodHint() {
384+
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
385+
typeHint.withMethod("privateMethod", Collections.emptyList(), ExecutableMode.INTROSPECT));
386+
assertPredicateMatches(reflection.onMethod(SampleClass.class, "privateMethod").introspect());
398387
}
399388

400389
@Test
@@ -464,15 +453,15 @@ void shouldFailForUnknownClass() {
464453
}
465454

466455
@Test
467-
void fieldReflectionMatchesFieldHint() {
468-
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
456+
void fieldReflectionMatchesTypeHint() {
457+
runtimeHints.reflection().registerType(SampleClass.class);
469458
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
470459
}
471460

472461
@Test
473-
void fieldReflectionDoesNotMatchNonRegisteredFielddHint() {
462+
void fieldReflectionMatchesFieldHint() {
474463
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
475-
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField"));
464+
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField"));
476465
}
477466

478467
@Test
@@ -482,21 +471,27 @@ void fieldReflectionMatchesPublicFieldsHint() {
482471
}
483472

484473
@Test
485-
void fieldReflectionDoesNotMatchDeclaredFieldsHint() {
486-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.DECLARED_FIELDS);
487-
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField"));
474+
void fieldInvocationMatchesPublicFieldsHint() {
475+
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_PUBLIC_FIELDS);
476+
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").invocation());
488477
}
489478

490479
@Test
491-
void privateFieldReflectionMatchesFieldHint() {
492-
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("privateField"));
480+
void fieldInvocationDoesNotMatchTypeHint() {
481+
runtimeHints.reflection().registerType(SampleClass.class);
482+
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").invocation());
483+
}
484+
485+
@Test
486+
void privateFieldReflectionMatchesTypeHint() {
487+
runtimeHints.reflection().registerType(SampleClass.class);
493488
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
494489
}
495490

496491
@Test
497-
void privateFieldReflectionDoesNotMatchPublicFieldsHint() {
498-
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.PUBLIC_FIELDS);
499-
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField"));
492+
void privateFieldReflectionMatchesFieldHint() {
493+
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("privateField"));
494+
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
500495
}
501496

502497
@Test
@@ -505,6 +500,18 @@ void privateFieldReflectionMatchesDeclaredFieldsHint() {
505500
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField"));
506501
}
507502

503+
@Test
504+
void privateFieldInvocationMatchesDeclaredFieldsHint() {
505+
runtimeHints.reflection().registerType(SampleClass.class, MemberCategory.INVOKE_DECLARED_FIELDS);
506+
assertPredicateMatches(reflection.onField(SampleClass.class, "privateField").invocation());
507+
}
508+
509+
@Test
510+
void privateFieldInvocationDoesNotMatchTypeHint() {
511+
runtimeHints.reflection().registerType(SampleClass.class);
512+
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField").invocation());
513+
}
514+
508515
}
509516

510517
private void assertPredicateMatches(Predicate<RuntimeHints> predicate) {

‎spring-core/src/test/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrarTests.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,8 @@ void registerWithNonExistingLocationDoesNotRegisterHint() {
140140
}
141141

142142
private Consumer<ResourcePatternHints> includes(String... patterns) {
143-
return hint -> {
144-
assertThat(hint.getIncludes().stream().map(ResourcePatternHint::getPattern))
145-
.containsExactlyInAnyOrder(patterns);
146-
assertThat(hint.getExcludes()).isEmpty();
147-
};
143+
return hint -> assertThat(hint.getIncludes().stream().map(ResourcePatternHint::getPattern))
144+
.containsExactlyInAnyOrder(patterns);
148145
}
149146

150147
}

0 commit comments

Comments
 (0)
Please sign in to comment.