From 279390912353294f986195dc194c3b6cfa3c99bf Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Jul 2024 14:41:56 +0300 Subject: [PATCH] Improve reflection registrations in picocli extension Picocli invokes getDeclaredFields on the declaring classes of annotated fields so we need to register all fields instead of just the annotated ones to avoid `MissingReflectionRegistrationError`s at run-time when using `-H:+ThrowMissingRegistrationErrors` or `--exact-reachability-metadata`. Relates to https://github.com/quarkusio/quarkus/issues/41995 --- .../deployment/PicocliNativeImageProcessor.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/extensions/picocli/deployment/src/main/java/io/quarkus/picocli/deployment/PicocliNativeImageProcessor.java b/extensions/picocli/deployment/src/main/java/io/quarkus/picocli/deployment/PicocliNativeImageProcessor.java index fd20931917716f..00e1b340d0f531 100644 --- a/extensions/picocli/deployment/src/main/java/io/quarkus/picocli/deployment/PicocliNativeImageProcessor.java +++ b/extensions/picocli/deployment/src/main/java/io/quarkus/picocli/deployment/PicocliNativeImageProcessor.java @@ -16,7 +16,6 @@ import org.jboss.jandex.AnnotationValue.Kind; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; -import org.jboss.jandex.FieldInfo; import org.jboss.jandex.IndexView; import org.jboss.jandex.Type; import org.jboss.logging.Logger; @@ -55,7 +54,6 @@ void reflectionConfiguration(CombinedIndexBuildItem combinedIndexBuildItem, DotName.createSimple(CommandLine.Unmatched.class.getName())); Set foundClasses = new HashSet<>(); - Set foundFields = new HashSet<>(); Set typeAnnotationValues = new HashSet<>(); for (DotName analyzedAnnotation : annotationsToAnalyze) { @@ -66,7 +64,6 @@ void reflectionConfiguration(CombinedIndexBuildItem combinedIndexBuildItem, foundClasses.add(target.asClass()); break; case FIELD: - foundFields.add(target.asField()); // This may be class which will be used as Mixin. We need to be sure that Picocli will be able // to initialize those even if they are not beans. foundClasses.add(target.asField().declaringClass()); @@ -94,20 +91,18 @@ void reflectionConfiguration(CombinedIndexBuildItem combinedIndexBuildItem, } } + // Register both declared methods and fields as they are accessed by picocli during initialization foundClasses.forEach(classInfo -> { if (Modifier.isInterface(classInfo.flags())) { nativeImageProxies .produce(new NativeImageProxyDefinitionBuildItem(classInfo.name().toString())); - reflectiveClasses - .produce(ReflectiveClassBuildItem.builder(classInfo.name().toString()).constructors(false).methods() - .build()); + reflectiveClasses.produce(ReflectiveClassBuildItem.builder(classInfo.name().toString()).constructors(false) + .methods().fields().build()); } else { reflectiveClasses - .produce(ReflectiveClassBuildItem.builder(classInfo.name().toString()).methods() - .build()); + .produce(ReflectiveClassBuildItem.builder(classInfo.name().toString()).methods().fields().build()); } }); - foundFields.forEach(fieldInfo -> reflectiveFields.produce(new ReflectiveFieldBuildItem(fieldInfo))); typeAnnotationValues.forEach(type -> reflectiveHierarchies.produce(ReflectiveHierarchyBuildItem .builder(type) .source(PicocliNativeImageProcessor.class.getSimpleName())