Skip to content

Commit c09e69a

Browse files
committed
Introduce reason field in ReflectiveClassBuildItem
The aim of this field is to hold the reason why we need to register this class for reflection for debugging/observation purposes.
1 parent 0fc1aa5 commit c09e69a

File tree

72 files changed

+545
-314
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+545
-314
lines changed

core/deployment/src/main/java/io/quarkus/deployment/CollectionClassProcessor.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
public class CollectionClassProcessor {
99
@BuildStep
1010
ReflectiveClassBuildItem setupCollectionClasses() {
11-
return ReflectiveClassBuildItem.builder(ArrayList.class.getName(),
12-
HashMap.class.getName(),
13-
HashSet.class.getName(),
14-
LinkedList.class.getName(),
15-
LinkedHashMap.class.getName(),
16-
LinkedHashSet.class.getName(),
17-
TreeMap.class.getName(),
18-
TreeSet.class.getName()).build();
11+
return ReflectiveClassBuildItem.builder(ArrayList.class,
12+
HashMap.class,
13+
HashSet.class,
14+
LinkedList.class,
15+
LinkedHashMap.class,
16+
LinkedHashSet.class,
17+
TreeMap.class,
18+
TreeSet.class).reason(getClass().getName()).build();
1919
}
2020
}

core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public final class ReflectiveClassBuildItem extends MultiBuildItem {
2424
private final boolean weak;
2525
private final boolean serialization;
2626
private final boolean unsafeAllocated;
27+
private final String reason;
2728

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

4546
private ReflectiveClassBuildItem(boolean constructors, boolean queryConstructors, boolean methods, boolean queryMethods,
46-
boolean fields, boolean getClasses, boolean weak, boolean serialization,
47-
boolean unsafeAllocated, Class<?>... classes) {
47+
boolean fields, boolean getClasses, boolean weak, boolean serialization, boolean unsafeAllocated, String reason,
48+
Class<?>... classes) {
4849
this(constructors, queryConstructors, methods, queryMethods, fields, getClasses, weak, serialization,
49-
unsafeAllocated, stream(classes).map(Class::getName).toArray(String[]::new));
50+
unsafeAllocated, reason, stream(classes).map(Class::getName).toArray(String[]::new));
5051
}
5152

5253
/**
@@ -64,7 +65,7 @@ public ReflectiveClassBuildItem(boolean methods, boolean fields, Class<?>... cla
6465
*/
6566
@Deprecated(since = "3.0", forRemoval = true)
6667
public ReflectiveClassBuildItem(boolean constructors, boolean methods, boolean fields, Class<?>... classes) {
67-
this(constructors, false, methods, false, fields, false, false, false, false, classes);
68+
this(constructors, false, methods, false, fields, false, false, false, false, null, classes);
6869
}
6970

7071
/**
@@ -118,12 +119,12 @@ public static ReflectiveClassBuildItem serializationClass(String... classNames)
118119
boolean fields, boolean weak, boolean serialization,
119120
boolean unsafeAllocated, String... className) {
120121
this(constructors, queryConstructors, methods, queryMethods, fields, false, weak, serialization, unsafeAllocated,
121-
className);
122+
null, className);
122123
}
123124

124125
ReflectiveClassBuildItem(boolean constructors, boolean queryConstructors, boolean methods, boolean queryMethods,
125126
boolean fields, boolean classes, boolean weak, boolean serialization,
126-
boolean unsafeAllocated, String... className) {
127+
boolean unsafeAllocated, String reason, String... className) {
127128
for (String i : className) {
128129
if (i == null) {
129130
throw new NullPointerException();
@@ -153,6 +154,7 @@ public static ReflectiveClassBuildItem serializationClass(String... classNames)
153154
this.weak = weak;
154155
this.serialization = serialization;
155156
this.unsafeAllocated = unsafeAllocated;
157+
this.reason = reason;
156158
}
157159

158160
public List<String> getClassNames() {
@@ -204,6 +206,10 @@ public boolean isUnsafeAllocated() {
204206
return unsafeAllocated;
205207
}
206208

209+
public String getReason() {
210+
return reason;
211+
}
212+
207213
public static class Builder {
208214
private String[] className;
209215
private boolean constructors = true;
@@ -215,6 +221,7 @@ public static class Builder {
215221
private boolean weak;
216222
private boolean serialization;
217223
private boolean unsafeAllocated;
224+
private String reason;
218225

219226
private Builder() {
220227
}
@@ -341,13 +348,18 @@ public Builder unsafeAllocated(boolean unsafeAllocated) {
341348
return this;
342349
}
343350

351+
public Builder reason(String reason) {
352+
this.reason = reason;
353+
return this;
354+
}
355+
344356
public Builder unsafeAllocated() {
345357
return unsafeAllocated(true);
346358
}
347359

348360
public ReflectiveClassBuildItem build() {
349361
return new ReflectiveClassBuildItem(constructors, queryConstructors, methods, queryMethods, fields, classes, weak,
350-
serialization, unsafeAllocated, className);
362+
serialization, unsafeAllocated, reason, className);
351363
}
352364
}
353365
}

core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ private static void processConfigClass(
119119
classBytes));
120120
additionalConstrainedClasses.produce(AdditionalConstrainedClassBuildItem.of(mappingMetadata.getClassName(),
121121
classBytes));
122-
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName()).constructors().build());
122+
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName())
123+
.reason(ConfigMappingUtils.class.getName())
124+
.build());
123125
reflectiveMethods
124126
.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getDefaults", new String[0]));
125127
reflectiveMethods.produce(new ReflectiveMethodBuildItem(mappingMetadata.getClassName(), "getNames", new String[0]));
@@ -141,6 +143,8 @@ private static void processProperties(
141143
ConfigMappingInterface mapping = ConfigMappingLoader.getConfigMapping(configClass);
142144
for (Property property : mapping.getProperties()) {
143145
Class<?> returnType = property.getMethod().getReturnType();
146+
String reason = ConfigMappingUtils.class.getSimpleName() + " Required to process property "
147+
+ property.getPropertyName();
144148

145149
if (property.hasConvertWith()) {
146150
Class<? extends Converter<?>> convertWith;
@@ -149,39 +153,44 @@ private static void processProperties(
149153
} else {
150154
convertWith = property.asPrimitive().getConvertWith();
151155
}
152-
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(convertWith).build());
156+
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(convertWith).reason(reason).build());
153157
}
154158

155-
registerImplicitConverter(property, reflectiveClasses);
159+
registerImplicitConverter(property, reason, reflectiveClasses);
156160

157161
if (property.isMap()) {
158162
MapProperty mapProperty = property.asMap();
159163
if (mapProperty.hasKeyConvertWith()) {
160-
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyConvertWith()).build());
164+
reflectiveClasses
165+
.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyConvertWith()).reason(reason).build());
161166
} else {
162-
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyRawType()).build());
167+
reflectiveClasses
168+
.produce(ReflectiveClassBuildItem.builder(mapProperty.getKeyRawType()).reason(reason).build());
163169
}
164170

165-
registerImplicitConverter(mapProperty.getValueProperty(), reflectiveClasses);
171+
registerImplicitConverter(mapProperty.getValueProperty(), reason, reflectiveClasses);
166172
}
167173
}
168174
}
169175

170176
private static void registerImplicitConverter(
171177
Property property,
172-
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
178+
String reason, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
173179

174180
if (property.isLeaf() && !property.isOptional()) {
175181
LeafProperty leafProperty = property.asLeaf();
176182
if (leafProperty.hasConvertWith()) {
177-
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(leafProperty.getConvertWith()).build());
183+
reflectiveClasses
184+
.produce(ReflectiveClassBuildItem.builder(leafProperty.getConvertWith()).reason(reason).build());
178185
} else {
179-
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(leafProperty.getValueRawType()).methods().build());
186+
reflectiveClasses
187+
.produce(ReflectiveClassBuildItem.builder(leafProperty.getValueRawType()).reason(reason).methods()
188+
.build());
180189
}
181190
} else if (property.isOptional()) {
182-
registerImplicitConverter(property.asOptional().getNestedProperty(), reflectiveClasses);
191+
registerImplicitConverter(property.asOptional().getNestedProperty(), reason, reflectiveClasses);
183192
} else if (property.isCollection()) {
184-
registerImplicitConverter(property.asCollection().getElement(), reflectiveClasses);
193+
registerImplicitConverter(property.asCollection().getElement(), reason, reflectiveClasses);
185194
}
186195
}
187196

core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ LoggingSetupBuildItem setupLoggingRuntimeInit(RecorderContext context, LoggingSe
290290
if (!discoveredLogComponents.getNameToFilterClass().isEmpty()) {
291291
reflectiveClassBuildItemBuildProducer.produce(
292292
ReflectiveClassBuildItem.builder(discoveredLogComponents.getNameToFilterClass().values().toArray(
293-
EMPTY_STRING_ARRAY)).build());
293+
EMPTY_STRING_ARRAY)).reason(getClass().getName()).build());
294294
serviceProviderBuildItemBuildProducer
295295
.produce(ServiceProviderBuildItem.allProvidersFromClassPath(LogFilterFactory.class.getName()));
296296
}

core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void buildTimeRunTimeConfig(
157157
method.returnValue(configBuilder);
158158
}
159159

160-
reflectiveClass.produce(ReflectiveClassBuildItem.builder(builderClassName).build());
160+
reflectiveClass.produce(ReflectiveClassBuildItem.builder(builderClassName).reason(getClass().getName()).build());
161161
staticInitConfigBuilder.produce(new StaticInitConfigBuilderBuildItem(builderClassName));
162162
runTimeConfigBuilder.produce(new RunTimeConfigBuilderBuildItem(builderClassName));
163163
}

core/deployment/src/main/java/io/quarkus/deployment/steps/MainClassBuildStep.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ private void writeRecordedBytecode(BytecodeRecorderImpl recorder, String fallbac
512512
*/
513513
@BuildStep
514514
ReflectiveClassBuildItem applicationReflection() {
515-
return ReflectiveClassBuildItem.builder(Application.APP_CLASS_NAME).build();
515+
return ReflectiveClassBuildItem.builder(Application.APP_CLASS_NAME).reason("The generated application class").build();
516516
}
517517

518518
/**

core/deployment/src/main/java/io/quarkus/deployment/steps/ReflectiveHierarchyStep.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem
228228
.fields()
229229
.classes()
230230
.serialization(reflectiveHierarchyBuildItem.isSerialization())
231+
.reason(source)
231232
.build());
232233

233234
processedReflectiveHierarchies.add(name);

extensions/amazon-lambda-http/deployment/src/main/java/io/quarkus/amazon/lambda/http/deployment/AmazonLambdaHttpProcessor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public void registerReflectionClasses(BuildProducer<ReflectiveClassBuildItem> re
8686
APIGatewayV2HTTPEvent.RequestContext.IAM.class,
8787
APIGatewayV2HTTPEvent.RequestContext.Authorizer.JWT.class,
8888
APIGatewayV2HTTPResponse.class, Headers.class, MultiValuedTreeMap.class)
89+
.reason(getClass().getName())
8990
.methods().fields().build());
9091
}
9192

extensions/amazon-lambda-rest/deployment/src/main/java/io/quarkus/amazon/lambda/http/deployment/AmazonLambdaHttpProcessor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ public void registerReflectionClasses(BuildProducer<ReflectiveClassBuildItem> re
8787
CognitoAuthorizerClaims.class,
8888
ErrorModel.class,
8989
Headers.class,
90-
MultiValuedTreeMap.class).methods().fields().build());
90+
MultiValuedTreeMap.class)
91+
.reason(getClass().getName())
92+
.methods().fields().build());
9193
}
9294

9395
/**

extensions/amazon-lambda/deployment/src/main/java/io/quarkus/amazon/lambda/deployment/AmazonLambdaProcessor.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ List<AmazonLambdaBuildItem> discover(CombinedIndexBuildItem combinedIndexBuildIt
142142
additionalBeanBuildItemBuildProducer.produce(builder.build());
143143
reflectiveClassBuildItemBuildProducer
144144
.produce(ReflectiveClassBuildItem.builder(FunctionError.class).methods().fields()
145+
.reason(getClass().getName())
145146
.build());
146147
return ret;
147148
}
@@ -159,7 +160,9 @@ void processProvidedLambda(Optional<ProvidedAmazonLambdaHandlerBuildItem> provid
159160
additionalBeanBuildItemBuildProducer.produce(builder.build());
160161

161162
reflectiveClassBuildItemBuildProducer
162-
.produce(ReflectiveClassBuildItem.builder(handlerClass).methods().fields().build());
163+
.produce(ReflectiveClassBuildItem.builder(handlerClass).methods().fields()
164+
.reason(getClass().getName())
165+
.build());
163166

164167
// TODO
165168
// This really isn't good enough. We should recursively add reflection for all method and field types of the parameter
@@ -172,12 +175,16 @@ void processProvidedLambda(Optional<ProvidedAmazonLambdaHandlerBuildItem> provid
172175
if (!parameterTypes[0].equals(Object.class)) {
173176
reflectiveClassBuildItemBuildProducer
174177
.produce(ReflectiveClassBuildItem.builder(parameterTypes[0].getName())
178+
.reason(getClass().getName() + " > " + method.getName() + " first parameter type")
175179
.methods().fields().build());
176180
reflectiveClassBuildItemBuildProducer
177181
.produce(ReflectiveClassBuildItem.builder(method.getReturnType().getName())
182+
.reason(getClass().getName() + " > " + method.getName() + " return type")
183+
.methods().fields().build());
184+
reflectiveClassBuildItemBuildProducer
185+
.produce(ReflectiveClassBuildItem.builder(DateTime.class)
186+
.reason(getClass().getName())
178187
.methods().fields().build());
179-
reflectiveClassBuildItemBuildProducer.produce(ReflectiveClassBuildItem.builder(DateTime.class)
180-
.methods().fields().build());
181188
break;
182189
}
183190
}
@@ -313,7 +320,9 @@ void recordExpectedExceptions(LambdaBuildTimeConfig config,
313320
AmazonLambdaStaticRecorder recorder) {
314321
Set<Class<?>> classes = config.expectedExceptions.map(Set::copyOf).orElseGet(Set::of);
315322
classes.stream()
316-
.map(clazz -> ReflectiveClassBuildItem.builder(clazz).constructors(false).build())
323+
.map(clazz -> ReflectiveClassBuildItem.builder(clazz).constructors(false)
324+
.reason(getClass().getName() + " expectedExceptions")
325+
.build())
317326
.forEach(registerForReflection::produce);
318327
recorder.setExpectedExceptionClasses(classes);
319328
}

0 commit comments

Comments
 (0)