From 1cbabbd3e7d96ee9d83aae0160545c8cb196e735 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 fd20931917716..00e1b340d0f53 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())