Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
public class CollectionClassProcessor {
@BuildStep
ReflectiveClassBuildItem setupCollectionClasses() {
return ReflectiveClassBuildItem.builder(ArrayList.class.getName(),
HashMap.class.getName(),
HashSet.class.getName(),
LinkedList.class.getName(),
LinkedHashMap.class.getName(),
LinkedHashSet.class.getName(),
TreeMap.class.getName(),
TreeSet.class.getName()).build();
return ReflectiveClassBuildItem.builder(ArrayList.class,
HashMap.class,
HashSet.class,
LinkedList.class,
LinkedHashMap.class,
LinkedHashSet.class,
TreeMap.class,
TreeSet.class).reason(getClass().getName()).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ public class SecureRandomProcessor {
@BuildStep
void registerReflectiveMethods(BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods) {
// Called reflectively through java.security.SecureRandom.SecureRandom()
reflectiveMethods.produce(new ReflectiveMethodBuildItem("sun.security.provider.NativePRNG", "<init>",
reflectiveMethods.produce(new ReflectiveMethodBuildItem(
getClass().getName(),
"sun.security.provider.NativePRNG", "<init>",
java.security.SecureRandomParameters.class));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public final class ReflectiveClassBuildItem extends MultiBuildItem {
private final boolean weak;
private final boolean serialization;
private final boolean unsafeAllocated;
private final String reason;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this an array? At least the JSON example says it so

Copy link
Contributor Author

@zakkak zakkak Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each ReflectiveClassBuildItem has a single reason that it was created for, but you might have multiple ReflectiveClassBuildItems that were generated in different places for different reasons and refer to the same class. In this case you will get an array of reasons for this class registration. The relevant code is in https://github.com/quarkusio/quarkus/pull/42205/files#diff-3cb159eef1e3a292b96e837164047fe8be00767d4e8c2fba80d846ecdf4b8253


public static Builder builder(Class<?>... classes) {
String[] classNames = stream(classes)
Expand All @@ -43,10 +44,10 @@ public static Builder builder(String... classNames) {
}

private ReflectiveClassBuildItem(boolean constructors, boolean queryConstructors, boolean methods, boolean queryMethods,
boolean fields, boolean getClasses, boolean weak, boolean serialization,
boolean unsafeAllocated, Class<?>... classes) {
boolean fields, boolean getClasses, boolean weak, boolean serialization, boolean unsafeAllocated, String reason,
Class<?>... classes) {
this(constructors, queryConstructors, methods, queryMethods, fields, getClasses, weak, serialization,
unsafeAllocated, stream(classes).map(Class::getName).toArray(String[]::new));
unsafeAllocated, reason, stream(classes).map(Class::getName).toArray(String[]::new));
}

/**
Expand All @@ -64,7 +65,7 @@ public ReflectiveClassBuildItem(boolean methods, boolean fields, Class<?>... cla
*/
@Deprecated(since = "3.0", forRemoval = true)
public ReflectiveClassBuildItem(boolean constructors, boolean methods, boolean fields, Class<?>... classes) {
this(constructors, false, methods, false, fields, false, false, false, false, classes);
this(constructors, false, methods, false, fields, false, false, false, false, null, classes);
}

/**
Expand Down Expand Up @@ -118,12 +119,12 @@ public static ReflectiveClassBuildItem serializationClass(String... classNames)
boolean fields, boolean weak, boolean serialization,
boolean unsafeAllocated, String... className) {
this(constructors, queryConstructors, methods, queryMethods, fields, false, weak, serialization, unsafeAllocated,
className);
null, className);
}

ReflectiveClassBuildItem(boolean constructors, boolean queryConstructors, boolean methods, boolean queryMethods,
boolean fields, boolean classes, boolean weak, boolean serialization,
boolean unsafeAllocated, String... className) {
boolean unsafeAllocated, String reason, String... className) {
for (String i : className) {
if (i == null) {
throw new NullPointerException();
Expand Down Expand Up @@ -153,6 +154,7 @@ public static ReflectiveClassBuildItem serializationClass(String... classNames)
this.weak = weak;
this.serialization = serialization;
this.unsafeAllocated = unsafeAllocated;
this.reason = reason;
}

public List<String> getClassNames() {
Expand Down Expand Up @@ -204,6 +206,10 @@ public boolean isUnsafeAllocated() {
return unsafeAllocated;
}

public String getReason() {
return reason;
}

public static class Builder {
private String[] className;
private boolean constructors = true;
Expand All @@ -215,6 +221,7 @@ public static class Builder {
private boolean weak;
private boolean serialization;
private boolean unsafeAllocated;
private String reason;

private Builder() {
}
Expand Down Expand Up @@ -341,13 +348,18 @@ public Builder unsafeAllocated(boolean unsafeAllocated) {
return this;
}

public Builder reason(String reason) {
this.reason = reason;
return this;
}

public Builder unsafeAllocated() {
return unsafeAllocated(true);
}

public ReflectiveClassBuildItem build() {
return new ReflectiveClassBuildItem(constructors, queryConstructors, methods, queryMethods, fields, classes, weak,
serialization, unsafeAllocated, className);
serialization, unsafeAllocated, reason, className);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,24 @@ public final class ReflectiveFieldBuildItem extends MultiBuildItem {

final String declaringClass;
final String name;
final String reason;

public ReflectiveFieldBuildItem(FieldInfo field) {
public ReflectiveFieldBuildItem(String reason, FieldInfo field) {
this.reason = reason;
this.name = field.name();
this.declaringClass = field.declaringClass().name().toString();
}

public ReflectiveFieldBuildItem(FieldInfo field) {
this(null, field);
}

public ReflectiveFieldBuildItem(Field field) {
this(null, field);
}

public ReflectiveFieldBuildItem(String reason, Field field) {
this.reason = reason;
this.name = field.getName();
this.declaringClass = field.getDeclaringClass().getName();
}
Expand All @@ -28,4 +39,8 @@ public String getDeclaringClass() {
public String getName() {
return name;
}

public String getReason() {
return reason;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,65 @@ 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) {
this(false, 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,
Expand All @@ -67,13 +82,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() {
Expand All @@ -92,6 +101,10 @@ public boolean isQueryOnly() {
return queryOnly;
}

public String getReason() {
return reason;
}

@Override
public boolean equals(Object o) {
if (this == o)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,13 @@ private static void processConfigClass(
classBytes));
additionalConstrainedClasses.produce(AdditionalConstrainedClassBuildItem.of(mappingMetadata.getClassName(),
classBytes));
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName()).constructors().build());
reflectiveMethods
.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getDefaults", new String[0]));
reflectiveMethods.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getNames", new String[0]));
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName())
.reason(ConfigMappingUtils.class.getName())
.build());
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());

Expand All @@ -141,6 +144,8 @@ private static void processProperties(
ConfigMappingInterface mapping = ConfigMappingLoader.getConfigMapping(configClass);
for (Property property : mapping.getProperties()) {
Class<?> returnType = property.getMethod().getReturnType();
String reason = ConfigMappingUtils.class.getSimpleName() + " Required to process property "
+ property.getPropertyName();

if (property.hasConvertWith()) {
Class<? extends Converter<?>> convertWith;
Expand All @@ -149,39 +154,44 @@ private static void processProperties(
} else {
convertWith = property.asPrimitive().getConvertWith();
}
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(convertWith).build());
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(convertWith).reason(reason).build());
}

registerImplicitConverter(property, reflectiveClasses);
registerImplicitConverter(property, reason, reflectiveClasses);

if (property.isMap()) {
MapProperty mapProperty = property.asMap();
if (mapProperty.hasKeyConvertWith()) {
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyConvertWith()).build());
reflectiveClasses
.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyConvertWith()).reason(reason).build());
} else {
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyRawType()).build());
reflectiveClasses
.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyRawType()).reason(reason).build());
}

registerImplicitConverter(mapProperty.getValueProperty(), reflectiveClasses);
registerImplicitConverter(mapProperty.getValueProperty(), reason, reflectiveClasses);
}
}
}

private static void registerImplicitConverter(
Property property,
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
String reason, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {

if (property.isLeaf() && !property.isOptional()) {
LeafProperty leafProperty = property.asLeaf();
if (leafProperty.hasConvertWith()) {
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(leafProperty.getConvertWith()).build());
reflectiveClasses
.produce(ReflectiveClassBuildItem.builder(leafProperty.getConvertWith()).reason(reason).build());
} else {
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(leafProperty.getValueRawType()).methods().build());
reflectiveClasses
.produce(ReflectiveClassBuildItem.builder(leafProperty.getValueRawType()).reason(reason).methods()
.build());
}
} else if (property.isOptional()) {
registerImplicitConverter(property.asOptional().getNestedProperty(), reflectiveClasses);
registerImplicitConverter(property.asOptional().getNestedProperty(), reason, reflectiveClasses);
} else if (property.isCollection()) {
registerImplicitConverter(property.asCollection().getElement(), reflectiveClasses);
registerImplicitConverter(property.asCollection().getElement(), reason, reflectiveClasses);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ LoggingSetupBuildItem setupLoggingRuntimeInit(RecorderContext context, LoggingSe
if (!discoveredLogComponents.getNameToFilterClass().isEmpty()) {
reflectiveClassBuildItemBuildProducer.produce(
ReflectiveClassBuildItem.builder(discoveredLogComponents.getNameToFilterClass().values().toArray(
EMPTY_STRING_ARRAY)).build());
EMPTY_STRING_ARRAY)).reason(getClass().getName()).build());
serviceProviderBuildItemBuildProducer
.produce(ServiceProviderBuildItem.allProvidersFromClassPath(LogFilterFactory.class.getName()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,12 @@ interface Debug {
@WithDefault("false")
boolean enableDashboardDump();

/**
* Include a reasons entries in the generated json configuration files.
*/
@WithDefault("false")
boolean includeReasonsInConfigFiles();

/**
* Configure native executable compression using UPX.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void buildTimeRunTimeConfig(
method.returnValue(configBuilder);
}

reflectiveClass.produce(ReflectiveClassBuildItem.builder(builderClassName).build());
reflectiveClass.produce(ReflectiveClassBuildItem.builder(builderClassName).reason(getClass().getName()).build());
staticInitConfigBuilder.produce(new StaticInitConfigBuilderBuildItem(builderClassName));
runTimeConfigBuilder.produce(new RunTimeConfigBuilderBuildItem(builderClassName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ private void writeRecordedBytecode(BytecodeRecorderImpl recorder, String fallbac
*/
@BuildStep
ReflectiveClassBuildItem applicationReflection() {
return ReflectiveClassBuildItem.builder(Application.APP_CLASS_NAME).build();
return ReflectiveClassBuildItem.builder(Application.APP_CLASS_NAME).reason("The generated application class").build();
}

/**
Expand Down
Loading