From 067ae8434289f45e238b299228cf23a27fbd272b Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Mon, 13 May 2024 20:30:18 +0100 Subject: [PATCH 1/3] Simplify RecordingAnnotationsUtil --- .../recording/RecordingAnnotationsUtil.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/recording/RecordingAnnotationsUtil.java b/core/deployment/src/main/java/io/quarkus/deployment/recording/RecordingAnnotationsUtil.java index fe118e7c30a5c..5260c28d3b053 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/recording/RecordingAnnotationsUtil.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/recording/RecordingAnnotationsUtil.java @@ -4,7 +4,6 @@ import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.util.HashSet; -import java.util.List; import java.util.ServiceLoader; import java.util.Set; @@ -13,8 +12,8 @@ final class RecordingAnnotationsUtil { - static final List> IGNORED_PROPERTY_ANNOTATIONS; - static final List> RECORDABLE_CONSTRUCTOR_ANNOTATIONS; + private static final Class[] IGNORED_PROPERTY_ANNOTATIONS; + private static final Class[] RECORDABLE_CONSTRUCTOR_ANNOTATIONS; static { Set> ignoredPropertyAnnotations = new HashSet<>(); @@ -33,30 +32,32 @@ final class RecordingAnnotationsUtil { } } - IGNORED_PROPERTY_ANNOTATIONS = List.copyOf(ignoredPropertyAnnotations); - RECORDABLE_CONSTRUCTOR_ANNOTATIONS = List.copyOf(recordableConstructorAnnotations); + IGNORED_PROPERTY_ANNOTATIONS = ignoredPropertyAnnotations.toArray(new Class[0]); + RECORDABLE_CONSTRUCTOR_ANNOTATIONS = recordableConstructorAnnotations.toArray(new Class[0]); } private RecordingAnnotationsUtil() { } - static boolean isIgnored(AccessibleObject object) { - for (int i = 0; i < IGNORED_PROPERTY_ANNOTATIONS.size(); i++) { - Class annotation = IGNORED_PROPERTY_ANNOTATIONS.get(i); - if (object.isAnnotationPresent(annotation)) { - return true; - } - } - return false; + static boolean isIgnored(final AccessibleObject object) { + return annotationsMatch(object.getDeclaredAnnotations(), IGNORED_PROPERTY_ANNOTATIONS); } - static boolean isRecordableConstructor(Constructor ctor) { - for (int i = 0; i < RECORDABLE_CONSTRUCTOR_ANNOTATIONS.size(); i++) { - Class annotation = RECORDABLE_CONSTRUCTOR_ANNOTATIONS.get(i); - if (ctor.isAnnotationPresent(annotation)) { - return true; + static boolean isRecordableConstructor(final Constructor ctor) { + return annotationsMatch(ctor.getDeclaredAnnotations(), RECORDABLE_CONSTRUCTOR_ANNOTATIONS); + } + + private static boolean annotationsMatch( + final Annotation[] declaredAnnotations, + final Class[] typesToCheck) { + for (Class annotation : typesToCheck) { + for (Annotation declaredAnnotation : declaredAnnotations) { + if (declaredAnnotation.annotationType().equals(annotation)) { + return true; + } } } return false; } + } From c82ed8989ee5cf2a6facbf8deaee3cdc290bf458 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Mon, 13 May 2024 20:35:57 +0100 Subject: [PATCH 2/3] Potential problem in recognizing boolean getters --- .../java/io/quarkus/deployment/recording/PropertyUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/recording/PropertyUtils.java b/core/deployment/src/main/java/io/quarkus/deployment/recording/PropertyUtils.java index 25959c196c0a2..da8594e88766a 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/recording/PropertyUtils.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/recording/PropertyUtils.java @@ -43,7 +43,7 @@ public Property[] apply(Class type) { if (existingGetter == null || existingGetter.getReturnType().isAssignableFrom(i.getReturnType())) { getters.put(name, i); } - } else if (i.getName().startsWith("is") && i.getName().length() > 3 && i.getParameterCount() == 0 + } else if (i.getName().startsWith("is") && i.getName().length() > 2 && i.getParameterCount() == 0 && (i.getReturnType() == boolean.class || i.getReturnType() == Boolean.class)) { String name = Character.toLowerCase(i.getName().charAt(2)) + i.getName().substring(3); isGetters.put(name, i); From ad963893983cc8445cc43415ff283bd4e8efe898 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Mon, 13 May 2024 21:06:34 +0100 Subject: [PATCH 3/3] Avoid o^2 lookup for Fields, avoid NoSuchFieldException(s) --- .../recording/BytecodeRecorderImpl.java | 11 ++++----- .../deployment/recording/FieldsHelper.java | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 core/deployment/src/main/java/io/quarkus/deployment/recording/FieldsHelper.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java b/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java index ab33e0d209d4b..651d21b79eddc 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java @@ -1200,6 +1200,7 @@ public void prepare(MethodContext context) { Set handledProperties = new HashSet<>(); Property[] desc = PropertyUtils.getPropertyDescriptors(param); + FieldsHelper fieldsHelper = new FieldsHelper(param.getClass()); for (Property i : desc) { if (!i.getDeclaringClass().getPackageName().startsWith("java.")) { // check if the getter is ignored @@ -1207,13 +1208,9 @@ public void prepare(MethodContext context) { continue; } // check if the matching field is ignored - try { - Field field = param.getClass().getDeclaredField(i.getName()); - if (ignoreField(field)) { - continue; - } - } catch (NoSuchFieldException ignored) { - + Field field = fieldsHelper.getDeclaredField(i.getName()); + if (field != null && ignoreField(field)) { + continue; } } Integer ctorParamIndex = constructorParamNameMap.remove(i.name); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/recording/FieldsHelper.java b/core/deployment/src/main/java/io/quarkus/deployment/recording/FieldsHelper.java new file mode 100644 index 0000000000000..9c14b226b2f87 --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/recording/FieldsHelper.java @@ -0,0 +1,23 @@ +package io.quarkus.deployment.recording; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +final class FieldsHelper { + + private final Map fields; + + public FieldsHelper(final Class aClass) { + final Field[] declaredFields = aClass.getDeclaredFields(); + this.fields = new HashMap<>(declaredFields.length); + for (Field field : declaredFields) { + this.fields.put(field.getName(), field); + } + } + + //Returns the matching Field, or null if not existing + public Field getDeclaredField(final String name) { + return fields.get(name); + } +}