Skip to content

Commit

Permalink
Merge pull request quarkusio#45014 from gsmet/fix-reflective-warnings
Browse files Browse the repository at this point in the history
Fix issues in RegisterForReflection#registerFullHierarchy() handling
  • Loading branch information
gsmet authored Jan 9, 2025
2 parents 978ab4c + 4f37fc9 commit 985ecf5
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 165 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public boolean isQueryConstructors() {

/**
* @deprecated As of GraalVM 21.2 finalFieldsWritable is no longer needed when registering fields for reflection. This will
* be removed in a future verion of Quarkus.
* be removed in a future version of Quarkus.
*/
@Deprecated
public boolean areFinalFieldsWritable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ public final class ReflectiveHierarchyBuildItem extends MultiBuildItem {
private final Predicate<FieldInfo> ignoreFieldPredicate;
private final Predicate<MethodInfo> ignoreMethodPredicate;
private final String source;
private final boolean constructors;
private final boolean methods;
private final boolean fields;
private final boolean serialization;
private final boolean unsafeAllocated;
private final boolean ignoreNested;

/**
* @deprecated Use the Builder instead.
Expand Down Expand Up @@ -106,19 +111,25 @@ public ReflectiveHierarchyBuildItem(Type type, Predicate<DotName> ignoreTypePred
@Deprecated
public ReflectiveHierarchyBuildItem(Type type, IndexView index, Predicate<DotName> ignoreTypePredicate, String source) {
this(type, index, ignoreTypePredicate, DefaultIgnoreFieldPredicate.INSTANCE, DefaultIgnoreMethodPredicate.INSTANCE,
source, false);
source, true, true, true, false, false, true);
}

private ReflectiveHierarchyBuildItem(Type type, IndexView index, Predicate<DotName> ignoreTypePredicate,
Predicate<FieldInfo> ignoreFieldPredicate, Predicate<MethodInfo> ignoreMethodPredicate, String source,
boolean serialization) {
Predicate<FieldInfo> ignoreFieldPredicate, Predicate<MethodInfo> ignoreMethodPredicate,
String source, boolean constructors, boolean methods, boolean fields, boolean serialization,
boolean unsafeAllocated, boolean ignoreNested) {
this.type = type;
this.index = index;
this.ignoreTypePredicate = ignoreTypePredicate;
this.ignoreFieldPredicate = ignoreFieldPredicate;
this.ignoreMethodPredicate = ignoreMethodPredicate;
this.source = source;
this.constructors = constructors;
this.methods = methods;
this.fields = fields;
this.serialization = serialization;
this.unsafeAllocated = unsafeAllocated;
this.ignoreNested = ignoreNested;
}

public Type getType() {
Expand All @@ -145,10 +156,30 @@ public boolean hasSource() {
return source != null;
}

public boolean isConstructors() {
return constructors;
}

public boolean isMethods() {
return methods;
}

public boolean isFields() {
return fields;
}

public boolean isSerialization() {
return serialization;
}

public boolean isUnsafeAllocated() {
return unsafeAllocated;
}

public boolean isIgnoreNested() {
return ignoreNested;
}

public String getSource() {
return source;
}
Expand Down Expand Up @@ -204,7 +235,13 @@ public static class Builder {
private Predicate<FieldInfo> ignoreFieldPredicate = DefaultIgnoreFieldPredicate.INSTANCE;
private Predicate<MethodInfo> ignoreMethodPredicate = DefaultIgnoreMethodPredicate.INSTANCE;
private String source = UNKNOWN_SOURCE;
private boolean constructors = true;
private boolean methods = true;
private boolean fields = true;
private boolean serialization;
private boolean unsafeAllocated;
// when registering a hierarchy, we want to inspect what's actually needed and blindly include nested classes is not a good idea
private boolean ignoreNested = true;

/**
* @deprecated use {@link ReflectiveHierarchyBuildItem#builder(Type)},
Expand Down Expand Up @@ -277,14 +314,41 @@ public Builder source(String source) {
return this;
}

public Builder constructors(boolean constructors) {
this.constructors = constructors;
return this;
}

public Builder methods(boolean methods) {
this.methods = methods;
return this;
}

public Builder fields(boolean fields) {
this.fields = fields;
return this;
}

public Builder serialization(boolean serialization) {
this.serialization = serialization;
return this;
}

public Builder unsafeAllocated(boolean unsafeAllocated) {
this.unsafeAllocated = unsafeAllocated;
return this;
}

public Builder ignoreNested(boolean ignoreNested) {
this.ignoreNested = ignoreNested;
return this;
}

public ReflectiveHierarchyBuildItem build() {
return new ReflectiveHierarchyBuildItem(type, index, ignoreTypePredicate, ignoreFieldPredicate,
ignoreMethodPredicate, source, serialization);
ignoreMethodPredicate, source,
constructors, methods, fields, serialization, unsafeAllocated,
ignoreNested);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,12 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem
reflectiveClass.produce(
ReflectiveClassBuildItem
.builder(name.toString())
.methods()
.fields()
.constructors(reflectiveHierarchyBuildItem.isConstructors())
.methods(reflectiveHierarchyBuildItem.isMethods())
.fields(reflectiveHierarchyBuildItem.isFields())
.classes()
.serialization(reflectiveHierarchyBuildItem.isSerialization())
.unsafeAllocated(reflectiveHierarchyBuildItem.isUnsafeAllocated())
.reason(source)
.build());

Expand Down Expand Up @@ -272,21 +274,13 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem
}

// for Kotlin classes, we need to register the nested classes as well because companion classes are very often necessary at runtime
if (capabilities.isPresent(Capability.KOTLIN) && isKotlinClass(info)) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
Class<?>[] declaredClasses = classLoader.loadClass(info.name().toString()).getDeclaredClasses();
for (Class<?> clazz : declaredClasses) {
DotName dotName = DotName.createSimple(clazz.getName());
addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, source,
dotName, dotName,
processedReflectiveHierarchies, unindexedClasses,
finalFieldsWritable, reflectiveClass, visits);
}
} catch (ClassNotFoundException e) {
log.warnf(e, "Failed to load Class %s", info.name().toString());
if (!reflectiveHierarchyBuildItem.isIgnoreNested()
|| (capabilities.isPresent(Capability.KOTLIN) && isKotlinClass(info))) {
for (DotName memberClassName : info.memberClasses()) {
addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, source,
memberClassName, memberClassName, processedReflectiveHierarchies, unindexedClasses,
finalFieldsWritable, reflectiveClass, visits);
}

}
}

Expand Down
Loading

0 comments on commit 985ecf5

Please sign in to comment.