Skip to content

Commit

Permalink
Improve reflection registrations in picocli extension
Browse files Browse the repository at this point in the history
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 quarkusio#41995
  • Loading branch information
zakkak authored and holly-cummins committed Jul 31, 2024
1 parent f72f699 commit 2793909
Showing 1 changed file with 4 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -55,7 +54,6 @@ void reflectionConfiguration(CombinedIndexBuildItem combinedIndexBuildItem,
DotName.createSimple(CommandLine.Unmatched.class.getName()));

Set<ClassInfo> foundClasses = new HashSet<>();
Set<FieldInfo> foundFields = new HashSet<>();
Set<Type> typeAnnotationValues = new HashSet<>();

for (DotName analyzedAnnotation : annotationsToAnalyze) {
Expand All @@ -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());
Expand Down Expand Up @@ -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())
Expand Down

0 comments on commit 2793909

Please sign in to comment.