From 1cb5f0072335cc215e3c6ebc9cde325b5b0f24c1 Mon Sep 17 00:00:00 2001 From: SreenathTM Date: Sat, 10 Sep 2022 18:47:13 +0530 Subject: [PATCH 1/2] Adapt FieldHint to recent GraalVM versions In recent GraalVM versions, allowWrite and allowUnsafeAccess have been deprecated and are no longer use. This commit updates FieldHint to remove the irrelevant properties. See gh-29130 --- .../springframework/aot/hint/FieldHint.java | 144 ------------------ .../springframework/aot/hint/TypeHint.java | 36 +---- 2 files changed, 7 insertions(+), 173 deletions(-) delete mode 100644 spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java diff --git a/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java b/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java deleted file mode 100644 index 0587700ccb..0000000000 --- a/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2002-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.aot.hint; - -import java.lang.reflect.Field; -import java.util.function.Consumer; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * A hint that describes the need for reflection on a {@link Field}. - * - * @author Stephane Nicoll - * @since 6.0 - */ -public final class FieldHint extends MemberHint { - - private final FieldMode mode; - - private final boolean allowUnsafeAccess; - - - private FieldHint(Builder builder) { - super(builder.name); - this.mode = (builder.mode != null ? builder.mode : FieldMode.WRITE); - this.allowUnsafeAccess = builder.allowUnsafeAccess; - } - - /** - * Return whether setting the value of the field should be allowed. - * @return {@code true} to allow {@link Field#set(Object, Object)}. - * @deprecated in favor of {@link #getMode()} - */ - @Deprecated - public boolean isAllowWrite() { - return this.mode == FieldMode.WRITE; - } - - /** - * Return the {@linkplain FieldMode mode} that applies to this hint. - * @return the mode - */ - public FieldMode getMode() { - return this.mode; - } - - /** - * Return whether using {@code Unsafe} on the field should be allowed. - * @return {@code true} to allow unsafe access - */ - public boolean isAllowUnsafeAccess() { - return this.allowUnsafeAccess; - } - - /** - * Return a {@link Consumer} that applies the given {@link FieldMode} - * to the accepted {@link Builder}. - * @param mode the mode to apply - * @return a consumer to apply the mode - */ - public static Consumer builtWith(FieldMode mode) { - return builder -> builder.withMode(mode); - } - - - /** - * Builder for {@link FieldHint}. - */ - public static class Builder { - - private final String name; - - @Nullable - private FieldMode mode; - - private boolean allowUnsafeAccess; - - - Builder(String name) { - this.name = name; - } - - /** - * Specify if setting the value of the field should be allowed. - * @param allowWrite {@code true} to allow {@link Field#set(Object, Object)} - * @return {@code this}, to facilitate method chaining - * @deprecated in favor of {@link #withMode(FieldMode)} - */ - @Deprecated - public Builder allowWrite(boolean allowWrite) { - if (allowWrite) { - return withMode(FieldMode.WRITE); - } - return this; - } - - /** - * Specify that the {@linkplain FieldMode mode} is required. - * @param mode the required mode - * @return {@code this}, to facilitate method chaining - */ - public Builder withMode(FieldMode mode) { - Assert.notNull(mode, "'mode' must not be null"); - if ((this.mode == null || !this.mode.includes(mode))) { - this.mode = mode; - } - return this; - } - - /** - * Specify whether using {@code Unsafe} on the field should be allowed. - * @param allowUnsafeAccess {@code true} to allow unsafe access - * @return {@code this}, to facilitate method chaining - */ - public Builder allowUnsafeAccess(boolean allowUnsafeAccess) { - this.allowUnsafeAccess = allowUnsafeAccess; - return this; - } - - /** - * Create a {@link FieldHint} based on the state of this builder. - * @return a field hint - */ - FieldHint build() { - return new FieldHint(this); - } - - } -} diff --git a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java index 95432587ad..3de974f2e9 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java @@ -44,7 +44,7 @@ public final class TypeHint implements ConditionalHint { @Nullable private final TypeReference reachableType; - private final Set fields; + private final Set fields; private final Set constructors; @@ -57,7 +57,7 @@ public final class TypeHint implements ConditionalHint { this.type = builder.type; this.reachableType = builder.reachableType; this.memberCategories = Set.copyOf(builder.memberCategories); - this.fields = builder.fields.values().stream().map(FieldHint.Builder::build).collect(Collectors.toSet()); + this.fields = builder.fields; this.constructors = builder.constructors.values().stream().map(ExecutableHint.Builder::build).collect(Collectors.toSet()); this.methods = builder.methods.values().stream().map(ExecutableHint.Builder::build).collect(Collectors.toSet()); } @@ -89,10 +89,10 @@ public final class TypeHint implements ConditionalHint { /** * Return the fields that require reflection. - * @return a stream of {@link FieldHint} + * @return a stream of Strings */ - public Stream fields() { - return this.fields.stream(); + public Set fields() { + return this.fields; } /** @@ -147,7 +147,7 @@ public final class TypeHint implements ConditionalHint { @Nullable private TypeReference reachableType; - private final Map fields = new HashMap<>(); + private final Set fields = new HashSet<>(); private final Map constructors = new HashMap<>(); @@ -191,31 +191,9 @@ public final class TypeHint implements ConditionalHint { * @return {@code this}, to facilitate method chaining */ public Builder withField(String name) { - return withField(name, FieldMode.WRITE); + return withField(name); } - /** - * Register the need for reflection on the field with the specified name - * using the specified {@link FieldMode}. - * @param name the name of the field - * @param mode the requested mode - * @return {@code this}, to facilitate method chaining - */ - public Builder withField(String name, FieldMode mode) { - return withField(name, FieldHint.builtWith(mode)); - } - - /** - * Register the need for reflection on the field with the specified name. - * @param name the name of the field - * @param fieldHint a builder to further customize the hints of this field - * @return {@code this}, to facilitate method chaining - */ - public Builder withField(String name, Consumer fieldHint) { - FieldHint.Builder builder = this.fields.computeIfAbsent(name, FieldHint.Builder::new); - fieldHint.accept(builder); - return this; - } /** * Register the need for reflection on the constructor with the specified From 042a4f3518eae203c63d0db2b69ddc7fd9a61e3b Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 10 Sep 2022 15:56:26 +0200 Subject: [PATCH 2/2] Polish "Adapt FieldHint to recent GraalVM versions" See gh-29130 --- ...nBeanRegistrationAotContributionTests.java | 4 +- .../aot/agent/InstrumentedMethod.java | 2 +- .../springframework/aot/hint/FieldHint.java} | 19 +++--- .../springframework/aot/hint/FieldMode.java | 51 ---------------- .../aot/hint/ReflectionHints.java | 25 +------- .../springframework/aot/hint/TypeHint.java | 17 +++--- .../predicate/ReflectionHintsPredicates.java | 53 +--------------- .../aot/nativex/ReflectionHintsWriter.java | 7 --- .../aot/hint/FieldModeTests.java | 61 ------------------- .../aot/hint/ReflectionHintsTests.java | 57 +---------------- .../aot/hint/TypeHintTests.java | 57 +---------------- .../ReflectionHintsPredicatesTests.java | 28 +-------- .../FileNativeConfigurationWriterTests.java | 34 +++++------ .../nativex/ReflectionHintsWriterTests.java | 10 +-- .../support/InjectionCodeGeneratorTests.java | 2 +- ...BeanPostProcessorAotContributionTests.java | 10 +-- 16 files changed, 49 insertions(+), 388 deletions(-) rename spring-core/src/{test/java/org/springframework/aot/hint/FieldHintTests.java => main/java/org/springframework/aot/hint/FieldHint.java} (59%) delete mode 100644 spring-core/src/main/java/org/springframework/aot/hint/FieldMode.java delete mode 100644 spring-core/src/test/java/org/springframework/aot/hint/FieldModeTests.java diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java index 219093424e..5e425d305e 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java @@ -73,7 +73,7 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests { RegisteredBean registeredBean = getAndApplyContribution( PrivateFieldInjectionSample.class); assertThat(RuntimeHintsPredicates.reflection() - .onField(PrivateFieldInjectionSample.class, "environment").withWriteMode()) + .onField(PrivateFieldInjectionSample.class, "environment")) .accepts(this.generationContext.getRuntimeHints()); compile(registeredBean, (postProcessor, compiled) -> { PrivateFieldInjectionSample instance = new PrivateFieldInjectionSample(); @@ -92,7 +92,7 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests { RegisteredBean registeredBean = getAndApplyContribution( PackagePrivateFieldInjectionSample.class); assertThat(RuntimeHintsPredicates.reflection() - .onField(PackagePrivateFieldInjectionSample.class, "environment").withWriteMode()) + .onField(PackagePrivateFieldInjectionSample.class, "environment")) .accepts(this.generationContext.getRuntimeHints()); compile(registeredBean, (postProcessor, compiled) -> { PackagePrivateFieldInjectionSample instance = new PackagePrivateFieldInjectionSample(); diff --git a/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java b/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java index f7fc7e8a51..091cfbef58 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java +++ b/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java @@ -290,7 +290,7 @@ enum InstrumentedMethod { * {@link Field#set(Object, Object)}. */ FIELD_SET(Field.class, "set", HintType.REFLECTION, - invocation -> reflection().onField(invocation.getInstance()).withWriteMode()), + invocation -> reflection().onField(invocation.getInstance())), /* diff --git a/spring-core/src/test/java/org/springframework/aot/hint/FieldHintTests.java b/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java similarity index 59% rename from spring-core/src/test/java/org/springframework/aot/hint/FieldHintTests.java rename to spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java index 8c89a21e56..e2be3052bb 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/FieldHintTests.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/FieldHint.java @@ -16,23 +16,18 @@ package org.springframework.aot.hint; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; +import java.lang.reflect.Field; /** - * Tests for {@link FieldHint}. + * A hint that describes the need for reflection on a {@link Field}. * - * @author Phillip Webb + * @author Stephane Nicoll + * @since 6.0 */ -class FieldHintTests { +public final class FieldHint extends MemberHint { - @Test - void builtWithAppliesMode() { - FieldHint.Builder builder = new FieldHint.Builder("test"); - assertThat(builder.build().getMode()).isEqualTo(FieldMode.WRITE); - FieldHint.builtWith(FieldMode.READ).accept(builder); - assertThat(builder.build().getMode()).isEqualTo(FieldMode.READ); + FieldHint(String name) { + super(name); } } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/FieldMode.java b/spring-core/src/main/java/org/springframework/aot/hint/FieldMode.java deleted file mode 100644 index 289e479314..0000000000 --- a/spring-core/src/main/java/org/springframework/aot/hint/FieldMode.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2002-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.aot.hint; - -import java.lang.reflect.Field; - -import org.springframework.lang.Nullable; - -/** - * Represents the need of reflection for a given {@link Field}. - * - * @author Phillip Webb - * @since 6.0 - * @see ReflectionHints - */ -public enum FieldMode { - - /** - * Only field read is required. - */ - READ, - - /** - * Full field read and write is required. - */ - WRITE; - - /** - * Specify if this mode already includes the specified {@code other} mode. - * @param other the other mode to check - * @return {@code true} if this mode includes the other mode - */ - public boolean includes(@Nullable FieldMode other) { - return (other == null || this.ordinal() >= other.ordinal()); - } - -} diff --git a/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java b/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java index a656a74f35..e70e9d94cc 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java @@ -148,34 +148,13 @@ public class ReflectionHints { } /** - * Register the need for reflection on the specified {@link Field}, - * enabling {@link FieldMode#WRITE}. + * Register the need for reflection on the specified {@link Field}. * @param field the field that requires reflection * @return {@code this}, to facilitate method chaining */ public ReflectionHints registerField(Field field) { - return registerField(field, FieldMode.WRITE); - } - - /** - * Register the need for reflection on the specified {@link Field} - * using the specified {@link FieldMode}. - * @param field the field that requires reflection - * @return {@code this}, to facilitate method chaining - */ - public ReflectionHints registerField(Field field, FieldMode mode) { - return registerField(field, FieldHint.builtWith(mode)); - } - - /** - * Register the need for reflection on the specified {@link Field}. - * @param field the field that requires reflection - * @param fieldHint a builder to further customize the hints of this field - * @return {@code this}, to facilitate method chaining - */ - public ReflectionHints registerField(Field field, Consumer fieldHint) { return registerType(TypeReference.of(field.getDeclaringClass()), - typeHint -> typeHint.withField(field.getName(), fieldHint)); + typeHint -> typeHint.withField(field.getName())); } /** diff --git a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java index 3de974f2e9..f660ad3a3c 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/TypeHint.java @@ -44,7 +44,7 @@ public final class TypeHint implements ConditionalHint { @Nullable private final TypeReference reachableType; - private final Set fields; + private final Set fields; private final Set constructors; @@ -57,7 +57,7 @@ public final class TypeHint implements ConditionalHint { this.type = builder.type; this.reachableType = builder.reachableType; this.memberCategories = Set.copyOf(builder.memberCategories); - this.fields = builder.fields; + this.fields = builder.fields.stream().map(FieldHint::new).collect(Collectors.toSet()); this.constructors = builder.constructors.values().stream().map(ExecutableHint.Builder::build).collect(Collectors.toSet()); this.methods = builder.methods.values().stream().map(ExecutableHint.Builder::build).collect(Collectors.toSet()); } @@ -89,10 +89,10 @@ public final class TypeHint implements ConditionalHint { /** * Return the fields that require reflection. - * @return a stream of Strings + * @return a stream of {@link FieldHint} */ - public Set fields() { - return this.fields; + public Stream fields() { + return this.fields.stream(); } /** @@ -185,16 +185,15 @@ public final class TypeHint implements ConditionalHint { } /** - * Register the need for reflection on the field with the specified name, - * enabling write access. + * Register the need for reflection on the field with the specified name. * @param name the name of the field * @return {@code this}, to facilitate method chaining */ public Builder withField(String name) { - return withField(name); + this.fields.add(name); + return this; } - /** * Register the need for reflection on the constructor with the specified * parameter types, enabling {@link ExecutableMode#INVOKE}. diff --git a/spring-core/src/main/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicates.java b/spring-core/src/main/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicates.java index c745cff465..45110dccae 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicates.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicates.java @@ -28,8 +28,6 @@ import java.util.function.Predicate; import org.springframework.aot.hint.ExecutableHint; import org.springframework.aot.hint.ExecutableMode; -import org.springframework.aot.hint.FieldHint; -import org.springframework.aot.hint.FieldMode; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.ReflectionHints; import org.springframework.aot.hint.RuntimeHints; @@ -375,57 +373,10 @@ public class ReflectionHintsPredicates { private final Field field; - private FieldMode mode = FieldMode.READ; - - private boolean allowUnsafeAccess; - FieldHintPredicate(Field field) { this.field = field; } - /** - * Refine the current predicate to match if write access is allowed on the field. - * @return the refined {@link RuntimeHints} predicate - * @see FieldHint#isAllowWrite() - * @deprecated in favor of {@link #withReadMode()} or {@link #withWriteMode()} - */ - @Deprecated - public FieldHintPredicate allowWrite() { - this.mode = FieldMode.WRITE; - return this; - } - - /** - * Refine the current predicate to match if read access is allowed on the field. - * @return the refined {@link RuntimeHints} predicate - * @see FieldHint#getMode() - */ - public FieldHintPredicate withReadMode() { - // FieldMode.READ is already the default and should not override a writeMode() call. - return this; - } - - /** - * Refine the current predicate to match if write access is allowed on the field. - * @return the refined {@link RuntimeHints} predicate - * @see FieldHint#getMode() - */ - public FieldHintPredicate withWriteMode() { - this.mode = FieldMode.WRITE; - return this; - } - - - /** - * Refine the current predicate to match if unsafe access is allowed on the field. - * @return the refined {@link RuntimeHints} predicate - * @see FieldHint#isAllowUnsafeAccess() () - */ - public FieldHintPredicate allowUnsafeAccess() { - this.allowUnsafeAccess = true; - return this; - } - @Override public boolean test(RuntimeHints runtimeHints) { TypeHint typeHint = runtimeHints.reflection().getTypeHint(this.field.getDeclaringClass()); @@ -447,9 +398,7 @@ public class ReflectionHintsPredicates { private boolean exactMatch(TypeHint typeHint) { return typeHint.fields().anyMatch(fieldHint -> - this.field.getName().equals(fieldHint.getName()) - && (fieldHint.getMode().includes(this.mode)) - && (!this.allowUnsafeAccess || this.allowUnsafeAccess == fieldHint.isAllowUnsafeAccess())); + this.field.getName().equals(fieldHint.getName())); } } diff --git a/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java b/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java index 3e2f220f0a..8a2b3603b0 100644 --- a/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java +++ b/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java @@ -26,7 +26,6 @@ import java.util.stream.Stream; import org.springframework.aot.hint.ExecutableHint; import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.FieldHint; -import org.springframework.aot.hint.FieldMode; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.ReflectionHints; import org.springframework.aot.hint.TypeHint; @@ -78,12 +77,6 @@ class ReflectionHintsWriter { private Map toAttributes(FieldHint hint) { Map attributes = new LinkedHashMap<>(); attributes.put("name", hint.getName()); - if (hint.getMode() == FieldMode.WRITE) { - attributes.put("allowWrite", true); - } - if (hint.isAllowUnsafeAccess()) { - attributes.put("allowUnsafeAccess", hint.isAllowUnsafeAccess()); - } return attributes; } diff --git a/spring-core/src/test/java/org/springframework/aot/hint/FieldModeTests.java b/spring-core/src/test/java/org/springframework/aot/hint/FieldModeTests.java deleted file mode 100644 index bb6ecf6f04..0000000000 --- a/spring-core/src/test/java/org/springframework/aot/hint/FieldModeTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2002-2022 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.aot.hint; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link FieldMode}. - * - * @author Phillip Webb - * @since 6.0 - */ -class FieldModeTests { - - @Test - void writeIncludesNullMode() { - assertThat(FieldMode.WRITE.includes(null)).isTrue(); - } - - @Test - void writeIncludesRead() { - assertThat(FieldMode.WRITE.includes(FieldMode.READ)).isTrue(); - } - - @Test - void writeIncludesWrite() { - assertThat(FieldMode.WRITE.includes(FieldMode.WRITE)).isTrue(); - } - - @Test - void readIncludesNullMode() { - assertThat(FieldMode.READ.includes(null)).isTrue(); - } - - @Test - void readIncludesRead() { - assertThat(FieldMode.READ.includes(FieldMode.READ)).isTrue(); - } - - @Test - void readDoesNotIncludeWrite() { - assertThat(FieldMode.READ.includes(FieldMode.WRITE)).isFalse(); - } - -} diff --git a/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java b/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java index a7213d999a..b585609a06 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java @@ -124,63 +124,12 @@ class ReflectionHintsTests { } @Test - void registerFieldAllowsWriteByDefault() { + void registerField() { Field field = ReflectionUtils.findField(TestType.class, "field"); assertThat(field).isNotNull(); this.reflectionHints.registerField(field); - assertTestTypeFieldHint(fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("field"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); - } - - @Test - void registerFieldWithEmptyCustomizerAppliesConsistentDefault() { - Field field = ReflectionUtils.findField(TestType.class, "field"); - assertThat(field).isNotNull(); - this.reflectionHints.registerField(field, fieldHint -> {}); - assertTestTypeFieldHint(fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("field"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); - } - - @Test - void registerFieldWithCustomizerAppliesCustomization() { - Field field = ReflectionUtils.findField(TestType.class, "field"); - assertThat(field).isNotNull(); - this.reflectionHints.registerField(field, fieldHint -> - fieldHint.withMode(FieldMode.READ).allowUnsafeAccess(true)); - assertTestTypeFieldHint(fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("field"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ); - assertThat(fieldHint.isAllowUnsafeAccess()).isTrue(); - }); - } - - @Test - void registerFieldWithMode() { - Field field = ReflectionUtils.findField(TestType.class, "field"); - assertThat(field).isNotNull(); - this.reflectionHints.registerField(field, FieldMode.READ); - assertTestTypeFieldHint(fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("field"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ); - }); - } - - @Test // gh-29055 - void registerFieldWithCustomizersCannotDowngradeWrite() { - Field field = ReflectionUtils.findField(TestType.class, "field"); - assertThat(field).isNotNull(); - this.reflectionHints.registerField(field, FieldMode.WRITE); - this.reflectionHints.registerField(field, FieldMode.READ); - assertTestTypeFieldHint(fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("field"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - }); + assertTestTypeFieldHint(fieldHint -> + assertThat(fieldHint.getName()).isEqualTo("field")); } private void assertTestTypeFieldHint(Consumer fieldHint) { diff --git a/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java b/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java index aef5bebf9b..c0f5743562 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/TypeHintTests.java @@ -55,62 +55,9 @@ class TypeHintTests { } @Test - void createWithFieldAllowsWriteByDefault() { + void createWithField() { assertFieldHint(TypeHint.of(TypeReference.of(String.class)) - .withField("value"), fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("value"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); - } - - @Test - void createWithFieldAndEmptyCustomizerAppliesConsistentDefault() { - assertFieldHint(TypeHint.of(TypeReference.of(String.class)) - .withField("value", fieldHint -> {}), fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("value"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); - } - - @Test - void createWithFieldAndCustomizerAppliesCustomization() { - assertFieldHint(TypeHint.of(TypeReference.of(String.class)) - .withField("value", fieldHint -> { - fieldHint.withMode(FieldMode.READ); - fieldHint.allowUnsafeAccess(true); - }), fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("value"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ); - assertThat(fieldHint.isAllowUnsafeAccess()).isTrue(); - }); - } - - @Test - void createWithFieldReuseBuilder() { - Builder builder = TypeHint.of(TypeReference.of(String.class)); - builder.withField("value", fieldHint -> fieldHint.allowUnsafeAccess(true)); - builder.withField("value", fieldHint -> { - fieldHint.withMode(FieldMode.WRITE); - fieldHint.allowUnsafeAccess(false); - }); - assertFieldHint(builder, fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("value"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); - } - - @Test - void createFieldWithFieldMode() { - Builder builder = TypeHint.of(TypeReference.of(String.class)); - builder.withField("value", FieldMode.READ); - assertFieldHint(builder, fieldHint -> { - assertThat(fieldHint.getName()).isEqualTo("value"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); + .withField("value"), fieldHint -> assertThat(fieldHint.getName()).isEqualTo("value")); } void assertFieldHint(Builder builder, Consumer fieldHint) { diff --git a/spring-core/src/test/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicatesTests.java b/spring-core/src/test/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicatesTests.java index 6275105e44..ade56f2d0d 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicatesTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/predicate/ReflectionHintsPredicatesTests.java @@ -27,7 +27,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.ExecutableMode; -import org.springframework.aot.hint.FieldMode; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; @@ -261,7 +260,7 @@ class ReflectionHintsPredicatesTests { @Test void privateConstructorInvocationDoesNotMatchConstructorHint() { runtimeHints.reflection().registerType(SampleClass.class, typeHint -> - typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT)); + typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT)); assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke()); } @@ -480,30 +479,9 @@ class ReflectionHintsPredicatesTests { } @Test - void fieldWriteReflectionDoesNotMatchFieldHint() { - runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField", - FieldMode.READ)); - assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").withWriteMode()); - } - - @Test - void fieldUnsafeReflectionDoesNotMatchFieldHint() { + void fieldReflectionDoesNotMatchNonRegisteredFielddHint() { runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField")); - assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").allowUnsafeAccess()); - } - - @Test - void fieldWriteReflectionMatchesFieldHintWithWrite() { - runtimeHints.reflection().registerType(SampleClass.class, typeHint -> - typeHint.withField("publicField", FieldMode.WRITE)); - assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").withWriteMode()); - } - - @Test - void fieldUnsafeReflectionMatchesFieldHintWithUnsafe() { - runtimeHints.reflection().registerType(SampleClass.class, - typeHint -> typeHint.withField("publicField", fieldHint -> fieldHint.allowUnsafeAccess(true))); - assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").allowUnsafeAccess()); + assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField")); } @Test diff --git a/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java b/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java index 6f297cb3f8..2668180fa8 100644 --- a/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java +++ b/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java @@ -32,7 +32,6 @@ import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; import org.springframework.aot.hint.ExecutableMode; -import org.springframework.aot.hint.FieldMode; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.ProxyHints; import org.springframework.aot.hint.ReflectionHints; @@ -99,24 +98,19 @@ public class FileNativeConfigurationWriterTests { FileNativeConfigurationWriter generator = new FileNativeConfigurationWriter(tempDir); RuntimeHints hints = new RuntimeHints(); ReflectionHints reflectionHints = hints.reflection(); - reflectionHints.registerType(StringDecoder.class, builder -> { - builder - .onReachableType(String.class) - .withMembers(MemberCategory.PUBLIC_FIELDS, MemberCategory.DECLARED_FIELDS, - MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS, - MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES) - .withField("DEFAULT_CHARSET", fieldBuilder -> fieldBuilder.withMode(FieldMode.READ)) - .withField("defaultCharset", fieldBuilder -> { - fieldBuilder.withMode(FieldMode.WRITE); - fieldBuilder.allowUnsafeAccess(true); - }) - .withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT) - .withMethod("setDefaultCharset", TypeReference.listOf(Charset.class)) - .withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT); - }); + reflectionHints.registerType(StringDecoder.class, builder -> builder + .onReachableType(String.class) + .withMembers(MemberCategory.PUBLIC_FIELDS, MemberCategory.DECLARED_FIELDS, + MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS, + MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES) + .withField("DEFAULT_CHARSET") + .withField("defaultCharset") + .withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT) + .withMethod("setDefaultCharset", TypeReference.listOf(Charset.class)) + .withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT)); generator.write(hints); assertEquals(""" [ @@ -137,7 +131,7 @@ public class FileNativeConfigurationWriterTests { "allDeclaredClasses": true, "fields": [ { "name": "DEFAULT_CHARSET" }, - { "name": "defaultCharset", "allowWrite": true, "allowUnsafeAccess": true } + { "name": "defaultCharset" } ], "methods": [ { "name": "setDefaultCharset", "parameterTypes": [ "java.nio.charset.Charset" ] } diff --git a/spring-core/src/test/java/org/springframework/aot/nativex/ReflectionHintsWriterTests.java b/spring-core/src/test/java/org/springframework/aot/nativex/ReflectionHintsWriterTests.java index bcdb73b08b..0aa8bce133 100644 --- a/spring-core/src/test/java/org/springframework/aot/nativex/ReflectionHintsWriterTests.java +++ b/spring-core/src/test/java/org/springframework/aot/nativex/ReflectionHintsWriterTests.java @@ -27,7 +27,6 @@ import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; import org.springframework.aot.hint.ExecutableMode; -import org.springframework.aot.hint.FieldMode; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.ReflectionHints; import org.springframework.aot.hint.TypeReference; @@ -58,11 +57,8 @@ public class ReflectionHintsWriterTests { MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES) - .withField("DEFAULT_CHARSET", fieldBuilder -> fieldBuilder.withMode(FieldMode.READ)) - .withField("defaultCharset", fieldBuilder -> { - fieldBuilder.withMode(FieldMode.WRITE); - fieldBuilder.allowUnsafeAccess(true); - }) + .withField("DEFAULT_CHARSET") + .withField("defaultCharset") .withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT) .withMethod("setDefaultCharset", List.of(TypeReference.of(Charset.class))) .withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT)); @@ -85,7 +81,7 @@ public class ReflectionHintsWriterTests { "allDeclaredClasses": true, "fields": [ { "name": "DEFAULT_CHARSET" }, - { "name": "defaultCharset", "allowWrite": true, "allowUnsafeAccess": true } + { "name": "defaultCharset" } ], "methods": [ { "name": "setDefaultCharset", "parameterTypes": [ "java.nio.charset.Charset" ] } diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/InjectionCodeGeneratorTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/InjectionCodeGeneratorTests.java index 90fe9bdeb3..f71007d724 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/InjectionCodeGeneratorTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/InjectionCodeGeneratorTests.java @@ -87,7 +87,7 @@ class InjectionCodeGeneratorTests { TestBean bean = new TestBean(); Field field = ReflectionUtils.findField(bean.getClass(), "age"); this.generator.generateInjectionCode(field, INSTANCE_VARIABLE, CodeBlock.of("$L", 123)); - assertThat(RuntimeHintsPredicates.reflection().onField(TestBean.class, "age").withWriteMode()) + assertThat(RuntimeHintsPredicates.reflection().onField(TestBean.class, "age")) .accepts(this.hints); } diff --git a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessorAotContributionTests.java b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessorAotContributionTests.java index 7ce1e532c6..e68dde6a01 100644 --- a/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessorAotContributionTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessorAotContributionTests.java @@ -32,7 +32,6 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.aot.hint.FieldMode; import org.springframework.aot.hint.TypeReference; import org.springframework.aot.test.generate.TestGenerationContext; import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess; @@ -129,13 +128,8 @@ class PersistenceAnnotationBeanPostProcessorAotContributionTests { .singleElement().satisfies(typeHint -> { assertThat(typeHint.getType()).isEqualTo( TypeReference.of(DefaultPersistenceContextField.class)); - assertThat(typeHint.fields()).singleElement() - .satisfies(fieldHint -> { - assertThat(fieldHint.getName()) - .isEqualTo("entityManager"); - assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE); - assertThat(fieldHint.isAllowUnsafeAccess()).isFalse(); - }); + assertThat(typeHint.fields()).singleElement().satisfies(fieldHint -> + assertThat(fieldHint.getName()).isEqualTo("entityManager")); }); }); }