From 902fc899e24c91ae0ed7a85acab22f26c1e9712b Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 29 Jul 2024 17:05:22 +0300 Subject: [PATCH] Introduce `reason` field in `ReflectiveMethodBuildItem` --- .../deployment/SecureRandomProcessor.java | 4 +- .../ReflectiveMethodBuildItem.java | 68 +++++++++++-------- .../configuration/ConfigMappingUtils.java | 7 +- .../steps/NativeImageReflectConfigStep.java | 11 ++- .../quarkus/arc/deployment/ArcProcessor.java | 4 +- .../InterceptedStaticMethodsProcessor.java | 2 +- .../HibernateValidatorProcessor.java | 6 +- .../jackson/deployment/JacksonProcessor.java | 2 +- .../jsonb/deployment/JsonbProcessor.java | 4 +- .../SmallRyeFaultToleranceProcessor.java | 2 +- .../ClassConfigurationPropertiesUtil.java | 2 +- 11 files changed, 70 insertions(+), 42 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/SecureRandomProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/SecureRandomProcessor.java index 7eb9296a02446..6ecec735827d8 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/SecureRandomProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/SecureRandomProcessor.java @@ -9,7 +9,9 @@ public class SecureRandomProcessor { @BuildStep void registerReflectiveMethods(BuildProducer reflectiveMethods) { // Called reflectively through java.security.SecureRandom.SecureRandom() - reflectiveMethods.produce(new ReflectiveMethodBuildItem("sun.security.provider.NativePRNG", "", + reflectiveMethods.produce(new ReflectiveMethodBuildItem( + getClass().getName(), + "sun.security.provider.NativePRNG", "", java.security.SecureRandomParameters.class)); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveMethodBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveMethodBuildItem.java index 395488ba8df89..d22291618f03b 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveMethodBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveMethodBuildItem.java @@ -3,6 +3,7 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.Objects; +import java.util.stream.Collectors; import org.jboss.jandex.MethodInfo; @@ -14,20 +15,23 @@ public final class ReflectiveMethodBuildItem extends MultiBuildItem { final String name; final String[] params; final boolean queryOnly; + final String reason; public ReflectiveMethodBuildItem(MethodInfo methodInfo) { - this(false, methodInfo); + this(null, false, methodInfo); + } + + public ReflectiveMethodBuildItem(String reason, MethodInfo methodInfo) { + this(reason, false, methodInfo); } public ReflectiveMethodBuildItem(boolean queryOnly, MethodInfo methodInfo) { - String[] params = new String[methodInfo.parametersCount()]; - for (int i = 0; i < params.length; ++i) { - params[i] = methodInfo.parameterType(i).name().toString(); - } - this.name = methodInfo.name(); - this.params = params; - this.declaringClass = methodInfo.declaringClass().name().toString(); - this.queryOnly = queryOnly; + this(null, queryOnly, methodInfo); + } + + public ReflectiveMethodBuildItem(String reason, boolean queryOnly, MethodInfo methodInfo) { + this(reason, queryOnly, methodInfo.declaringClass().name().toString(), methodInfo.name(), + methodInfo.parameterTypes().stream().map(p -> p.name().toString()).toArray(String[]::new)); } public ReflectiveMethodBuildItem(Method method) { @@ -35,29 +39,41 @@ public ReflectiveMethodBuildItem(Method method) { } public ReflectiveMethodBuildItem(boolean queryOnly, Method method) { - this.params = new String[method.getParameterCount()]; - if (method.getParameterCount() > 0) { - Class[] parameterTypes = method.getParameterTypes(); - for (int i = 0; i < params.length; ++i) { - params[i] = parameterTypes[i].getName(); - } - } - this.name = method.getName(); - this.declaringClass = method.getDeclaringClass().getName(); - this.queryOnly = queryOnly; + this(null, queryOnly, method); + } + + public ReflectiveMethodBuildItem(String reason, boolean queryOnly, Method method) { + this(reason, queryOnly, method.getDeclaringClass().getName(), method.getName(), + Arrays.stream(method.getParameterTypes()).map(Class::getName).toArray(String[]::new)); } public ReflectiveMethodBuildItem(String declaringClass, String name, String... params) { - this(false, declaringClass, name, params); + this(null, false, declaringClass, name, params); + } + + public ReflectiveMethodBuildItem(String reason, String declaringClass, String name, + String... params) { + this(reason, false, declaringClass, name, params); } public ReflectiveMethodBuildItem(boolean queryOnly, String declaringClass, String name, + String... params) { + this(null, queryOnly, declaringClass, name, params); + } + + public ReflectiveMethodBuildItem(String reason, boolean queryOnly, String declaringClass, String name, String... params) { this.declaringClass = declaringClass; this.name = name; this.params = params; this.queryOnly = queryOnly; + this.reason = reason; + } + + public ReflectiveMethodBuildItem(String reason, String declaringClass, String name, + Class... params) { + this(reason, false, declaringClass, name, Arrays.stream(params).map(Class::getName).toArray(String[]::new)); } public ReflectiveMethodBuildItem(String declaringClass, String name, @@ -67,13 +83,7 @@ public ReflectiveMethodBuildItem(String declaringClass, String name, public ReflectiveMethodBuildItem(boolean queryOnly, String declaringClass, String name, Class... params) { - this.declaringClass = declaringClass; - this.name = name; - this.params = new String[params.length]; - for (int i = 0; i < params.length; ++i) { - this.params[i] = params[i].getName(); - } - this.queryOnly = queryOnly; + this(null, queryOnly, declaringClass, name, Arrays.stream(params).map(Class::getName).toArray(String[]::new)); } public String getName() { @@ -92,6 +102,10 @@ public boolean isQueryOnly() { return queryOnly; } + public String getReason() { + return reason; + } + @Override public boolean equals(Object o) { if (this == o) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java b/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java index a66f91a3e8b8f..546572ed3ef28 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java @@ -122,9 +122,10 @@ private static void processConfigClass( reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName()) .reason(ConfigMappingUtils.class.getName()) .build()); - reflectiveMethods - .produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getDefaults", new String[0])); - reflectiveMethods.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getNames", new String[0])); + reflectiveMethods.produce(new ReflectiveMethodBuildItem(ConfigMappingUtils.class.getName(), + mappingMetadata.getClassName(), "getDefaults", new String[0])); + reflectiveMethods.produce(new ReflectiveMethodBuildItem(ConfigMappingUtils.class.getName(), + mappingMetadata.getClassName(), "getNames", new String[0])); configComponentInterfaces.add(mappingMetadata.getInterfaceType()); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java index 1e162e6586636..989c9e27d6d65 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java @@ -54,11 +54,11 @@ void generateReflectConfig(BuildProducer reflectConf for (ServiceProviderBuildItem i : serviceProviderBuildItems) { for (String provider : i.providers()) { // Register the nullary constructor - addReflectiveMethod(reflectiveClasses, new ReflectiveMethodBuildItem(provider, "", new String[0])); + addReflectiveMethod(reflectiveClasses, new ReflectiveMethodBuildItem("Class registered as provider", provider, "", new String[0])); // Register public provider() method for lookkup to avoid throwing a MissingReflectionRegistrationError at run time. // See ServiceLoader#loadProvider and ServiceLoader#findStaticProviderMethod. addReflectiveMethod(reflectiveClasses, - new ReflectiveMethodBuildItem(true, provider, "provider", new String[0])); + new ReflectiveMethodBuildItem("Class registered as provider", true, provider, "provider", new String[0])); } } @@ -175,6 +175,13 @@ public void addReflectiveMethod(Map reflectiveClasses, R existing.methodSet.add(methodInfo); } } + String reason = methodInfo.getReason(); + if (reason != null) { + if (existing.reasons == null) { + existing.reasons = new HashSet<>(); + } + existing.reasons.add(reason); + } } public void addReflectiveClass(Map reflectiveClasses, Set forcedNonWeakClasses, diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcProcessor.java index 8f7f2b705e748..cc1213e8311ea 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ArcProcessor.java @@ -538,12 +538,12 @@ public void generateResources(ArcConfig config, @Override public void registerMethod(String declaringClass, String name, String... params) { - reflectiveMethods.produce(new ReflectiveMethodBuildItem(declaringClass, name, params)); + reflectiveMethods.produce(new ReflectiveMethodBuildItem(getClass().getName(), declaringClass, name, params)); } @Override public void registerMethod(MethodInfo methodInfo) { - reflectiveMethods.produce(new ReflectiveMethodBuildItem(methodInfo)); + reflectiveMethods.produce(new ReflectiveMethodBuildItem(getClass().getName(), methodInfo)); } @Override diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/staticmethods/InterceptedStaticMethodsProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/staticmethods/InterceptedStaticMethodsProcessor.java index 1aa676876fe5b..dcdb5593bb937 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/staticmethods/InterceptedStaticMethodsProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/staticmethods/InterceptedStaticMethodsProcessor.java @@ -351,7 +351,7 @@ private String implementInit(IndexView index, ClassCreator initializer, chainHandle, methodHandle, bindingsHandle, forwardingFunc); // Needed when running on native image - reflectiveMethods.produce(new ReflectiveMethodBuildItem(method)); + reflectiveMethods.produce(new ReflectiveMethodBuildItem(getClass().getName(), method)); // Call InterceptedStaticMethods.register() init.invokeStaticMethod(INTERCEPTED_STATIC_METHODS_REGISTER, init.load(interceptedStaticMethod.getHash()), diff --git a/extensions/hibernate-validator/deployment/src/main/java/io/quarkus/hibernate/validator/deployment/HibernateValidatorProcessor.java b/extensions/hibernate-validator/deployment/src/main/java/io/quarkus/hibernate/validator/deployment/HibernateValidatorProcessor.java index e3bf28c4371be..843879361cdff 100644 --- a/extensions/hibernate-validator/deployment/src/main/java/io/quarkus/hibernate/validator/deployment/HibernateValidatorProcessor.java +++ b/extensions/hibernate-validator/deployment/src/main/java/io/quarkus/hibernate/validator/deployment/HibernateValidatorProcessor.java @@ -504,7 +504,8 @@ public void build( } else if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) { contributeClass(classNamesToBeValidated, indexView, annotation.target().asMethod().declaringClass().name()); // we need to register the method for reflection as it could be a getter - reflectiveMethods.produce(new ReflectiveMethodBuildItem(annotation.target().asMethod())); + reflectiveMethods + .produce(new ReflectiveMethodBuildItem(getClass().getName(), annotation.target().asMethod())); contributeClassMarkedForCascadingValidation(classNamesToBeValidated, indexView, consideredAnnotation, annotation.target().asMethod().returnType()); contributeMethodsWithInheritedValidation(methodsWithInheritedValidation, indexView, @@ -535,7 +536,8 @@ public void build( } } else if (enclosingTarget.kind() == AnnotationTarget.Kind.METHOD) { contributeClass(classNamesToBeValidated, indexView, enclosingTarget.asMethod().declaringClass().name()); - reflectiveMethods.produce(new ReflectiveMethodBuildItem(enclosingTarget.asMethod())); + reflectiveMethods + .produce(new ReflectiveMethodBuildItem(getClass().getName(), enclosingTarget.asMethod())); if (annotation.target().asType().target() != null) { contributeClassMarkedForCascadingValidation(classNamesToBeValidated, indexView, consideredAnnotation, diff --git a/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java b/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java index b2977ecb38eb6..6ea3e98035b38 100644 --- a/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java +++ b/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java @@ -273,7 +273,7 @@ void register( // make sure we register the constructors and methods marked with @JsonCreator for reflection for (AnnotationInstance creatorInstance : index.getAnnotations(JSON_CREATOR)) { if (METHOD == creatorInstance.target().kind()) { - reflectiveMethod.produce(new ReflectiveMethodBuildItem(creatorInstance.target().asMethod())); + reflectiveMethod.produce(new ReflectiveMethodBuildItem(getClass().getName(), creatorInstance.target().asMethod())); } } diff --git a/extensions/jsonb/deployment/src/main/java/io/quarkus/jsonb/deployment/JsonbProcessor.java b/extensions/jsonb/deployment/src/main/java/io/quarkus/jsonb/deployment/JsonbProcessor.java index fd58fbf01ba89..388c52604ad1c 100644 --- a/extensions/jsonb/deployment/src/main/java/io/quarkus/jsonb/deployment/JsonbProcessor.java +++ b/extensions/jsonb/deployment/src/main/java/io/quarkus/jsonb/deployment/JsonbProcessor.java @@ -92,7 +92,9 @@ void build(BuildProducer reflectiveClass, ReflectiveClassBuildItem.builder("java.lang.String").build()); // Necessary for Yasson versions using MethodHandles (2.0+) - reflectiveMethod.produce(new ReflectiveMethodBuildItem("jdk.internal.misc.Unsafe", "putReference", Object.class, + reflectiveMethod.produce(new ReflectiveMethodBuildItem( + getClass().getName(), + "jdk.internal.misc.Unsafe", "putReference", Object.class, long.class, Object.class)); } diff --git a/extensions/smallrye-fault-tolerance/deployment/src/main/java/io/quarkus/smallrye/faulttolerance/deployment/SmallRyeFaultToleranceProcessor.java b/extensions/smallrye-fault-tolerance/deployment/src/main/java/io/quarkus/smallrye/faulttolerance/deployment/SmallRyeFaultToleranceProcessor.java index 2262a13fa9228..8ad9312182049 100644 --- a/extensions/smallrye-fault-tolerance/deployment/src/main/java/io/quarkus/smallrye/faulttolerance/deployment/SmallRyeFaultToleranceProcessor.java +++ b/extensions/smallrye-fault-tolerance/deployment/src/main/java/io/quarkus/smallrye/faulttolerance/deployment/SmallRyeFaultToleranceProcessor.java @@ -148,7 +148,7 @@ public void build(BuildProducer annotationsTran clazz.methods() .stream() .filter(it -> fallbackMethod.equals(it.name())) - .forEach(it -> reflectiveMethod.produce(new ReflectiveMethodBuildItem(it))); + .forEach(it -> reflectiveMethod.produce(new ReflectiveMethodBuildItem(getClass().getName(), it))); DotName superClass = clazz.superName(); if (superClass != null && !DotNames.OBJECT.equals(superClass)) { diff --git a/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java b/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java index a8b14681e05b9..45a4cc95bcc8e 100644 --- a/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java +++ b/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java @@ -305,7 +305,7 @@ private ResultHandle populateConfigObject(ClassLoader classLoader, ClassInfo con continue; } if (method.parameterType(0).name().equals(DotNames.STRING)) { - reflectiveMethods.produce(new ReflectiveMethodBuildItem(method)); + reflectiveMethods.produce(new ReflectiveMethodBuildItem(getClass().getName(), method)); break; } }