Skip to content

Commit

Permalink
Introduce build item to override weak reflection semantics
Browse files Browse the repository at this point in the history
(cherry picked from commit 96899e7)
  • Loading branch information
geoand authored and gsmet committed May 27, 2021
1 parent a313abe commit 5834d3b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.quarkus.deployment.builditem.nativeimage;

import io.quarkus.builder.item.MultiBuildItem;

/**
* Forces classes that have been registered for reflection using weak semantics, to revert to normal reflection registration
* semantics.
* Essentially if this build item is used for a class that has been registered with {@link ReflectiveClassBuildItem},
* the {@code weak} field of that class is effectively false, no matter what value was supplied when creating
* {@code ReflectiveClassBuildItem}
*/
public final class ForceNonWeakReflectiveClassBuildItem extends MultiBuildItem {

private final String className;

public ForceNonWeakReflectiveClassBuildItem(String className) {
this.className = className;
}

public String getClassName() {
return className;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.GeneratedNativeImageClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ForceNonWeakReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.JniRuntimeAccessBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
Expand Down Expand Up @@ -82,6 +83,7 @@ void generateFeature(BuildProducer<GeneratedNativeImageClassBuildItem> nativeIma
List<ReflectiveMethodBuildItem> reflectiveMethods,
List<ReflectiveFieldBuildItem> reflectiveFields,
List<ReflectiveClassBuildItem> reflectiveClassBuildItems,
List<ForceNonWeakReflectiveClassBuildItem> nonWeakReflectiveClassBuildItems,
List<ServiceProviderBuildItem> serviceProviderBuildItems,
List<UnsafeAccessedFieldBuildItem> unsafeAccessedFields,
List<JniRuntimeAccessBuildItem> jniRuntimeAccessibleClasses) {
Expand Down Expand Up @@ -259,8 +261,13 @@ public void write(String s, byte[] bytes) {
int count = 0;

final Map<String, ReflectionInfo> reflectiveClasses = new LinkedHashMap<>();
final Set<String> forcedNonWeakClasses = new HashSet<>();
for (ForceNonWeakReflectiveClassBuildItem nonWeakReflectiveClassBuildItem : nonWeakReflectiveClassBuildItems) {
forcedNonWeakClasses.add(nonWeakReflectiveClassBuildItem.getClassName());
}
for (ReflectiveClassBuildItem i : reflectiveClassBuildItems) {
addReflectiveClass(reflectiveClasses, i.isConstructors(), i.isMethods(), i.isFields(), i.areFinalFieldsWritable(),
addReflectiveClass(reflectiveClasses, forcedNonWeakClasses, i.isConstructors(), i.isMethods(), i.isFields(),
i.areFinalFieldsWritable(),
i.isWeak(),
i.getClassNames().toArray(new String[0]));
}
Expand All @@ -272,7 +279,7 @@ public void write(String s, byte[] bytes) {
}

for (ServiceProviderBuildItem i : serviceProviderBuildItems) {
addReflectiveClass(reflectiveClasses, true, false, false, false, false,
addReflectiveClass(reflectiveClasses, forcedNonWeakClasses, true, false, false, false, false,
i.providers().toArray(new String[] {}));
}

Expand Down Expand Up @@ -445,13 +452,15 @@ public void addReflectiveMethod(Map<String, ReflectionInfo> reflectiveClasses, R
}
}

public void addReflectiveClass(Map<String, ReflectionInfo> reflectiveClasses, boolean constructors, boolean method,
public void addReflectiveClass(Map<String, ReflectionInfo> reflectiveClasses, Set<String> forcedNonWeakClasses,
boolean constructors, boolean method,
boolean fields, boolean finalFieldsWritable, boolean weak,
String... className) {
for (String cl : className) {
ReflectionInfo existing = reflectiveClasses.get(cl);
if (existing == null) {
reflectiveClasses.put(cl, new ReflectionInfo(constructors, method, fields, finalFieldsWritable, weak));
reflectiveClasses.put(cl, new ReflectionInfo(constructors, method, fields, finalFieldsWritable,
!forcedNonWeakClasses.contains(cl) && weak));
} else {
if (constructors) {
existing.constructors = true;
Expand Down

0 comments on commit 5834d3b

Please sign in to comment.