diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java index e28be3c002a9a..58838837571e3 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java @@ -17,6 +17,7 @@ public final class ReflectiveClassBuildItem extends MultiBuildItem { private final List className; private final boolean methods; private final boolean queryMethods; + private final boolean queryPublicMethods; private final boolean fields; private final boolean classes; private final boolean constructors; @@ -45,7 +46,7 @@ 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) { - this(constructors, queryConstructors, methods, queryMethods, fields, getClasses, weak, serialization, + this(constructors, queryConstructors, methods, queryMethods, false, fields, getClasses, weak, serialization, unsafeAllocated, stream(classes).map(Class::getName).toArray(String[]::new)); } @@ -117,12 +118,12 @@ public static ReflectiveClassBuildItem serializationClass(String... classNames) ReflectiveClassBuildItem(boolean constructors, boolean queryConstructors, boolean methods, boolean queryMethods, boolean fields, boolean weak, boolean serialization, boolean unsafeAllocated, String... className) { - this(constructors, queryConstructors, methods, queryMethods, fields, false, weak, serialization, unsafeAllocated, + this(constructors, queryConstructors, methods, queryMethods, false, fields, false, weak, serialization, unsafeAllocated, className); } ReflectiveClassBuildItem(boolean constructors, boolean queryConstructors, boolean methods, boolean queryMethods, - boolean fields, boolean classes, boolean weak, boolean serialization, + boolean queryPublicMethods, boolean fields, boolean classes, boolean weak, boolean serialization, boolean unsafeAllocated, String... className) { for (String i : className) { if (i == null) { @@ -139,6 +140,7 @@ public static ReflectiveClassBuildItem serializationClass(String... classNames) } else { this.queryMethods = queryMethods; } + this.queryPublicMethods = queryPublicMethods; this.fields = fields; this.classes = classes; this.constructors = constructors; @@ -167,6 +169,10 @@ public boolean isQueryMethods() { return queryMethods; } + public boolean isQueryPublicMethods() { + return queryPublicMethods; + } + public boolean isFields() { return fields; } @@ -210,6 +216,7 @@ public static class Builder { private boolean queryConstructors; private boolean methods; private boolean queryMethods; + private boolean queryPublicMethods; private boolean fields; private boolean classes; private boolean weak; @@ -277,6 +284,20 @@ public Builder queryMethods() { return queryMethods(true); } + /** + * Configures whether declared methods should be registered for reflection, for query purposes only, + * i.e. {@link Class#getMethods()}. Setting this enables getting all declared methods for the class but + * does not allow invoking them reflectively. + */ + public Builder queryPublicMethods(boolean queryPublicMethods) { + this.queryPublicMethods = queryPublicMethods; + return this; + } + + public Builder queryPublicMethods() { + return queryPublicMethods(true); + } + /** * Configures whether fields should be registered for reflection. * Setting this enables getting all declared fields for the class as well as accessing them reflectively. @@ -346,8 +367,8 @@ public Builder unsafeAllocated() { } public ReflectiveClassBuildItem build() { - return new ReflectiveClassBuildItem(constructors, queryConstructors, methods, queryMethods, fields, classes, weak, - serialization, unsafeAllocated, className); + return new ReflectiveClassBuildItem(constructors, queryConstructors, methods, queryMethods, queryPublicMethods, + fields, classes, weak, serialization, unsafeAllocated, className); } } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java index 26dd98f230f61..6bd663338e3b6 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageReflectConfigStep.java @@ -103,6 +103,9 @@ void generateReflectConfig(BuildProducer reflectConf extractToJsonArray(info.queriedMethodSet, queriedMethodsArray); } } + if (info.queryPublicMethods) { + json.put("queryAllPublicMethods", true); + } if (!methodsArray.isEmpty()) { json.put("methods", methodsArray); } @@ -188,6 +191,9 @@ public void addReflectiveClass(Map reflectiveClasses, Se if (classBuildItem.isQueryMethods()) { existing.queryMethods = true; } + if (classBuildItem.isQueryPublicMethods()) { + existing.queryPublicMethods = true; + } if (classBuildItem.isFields()) { existing.fields = true; } @@ -218,6 +224,7 @@ static final class ReflectionInfo { boolean queryConstructors; boolean methods; boolean queryMethods; + boolean queryPublicMethods; boolean fields; boolean classes; boolean serialization; @@ -234,6 +241,7 @@ private ReflectionInfo() { private ReflectionInfo(ReflectiveClassBuildItem classBuildItem, String typeReachable) { this.methods = classBuildItem.isMethods(); this.queryMethods = classBuildItem.isQueryMethods(); + this.queryPublicMethods = classBuildItem.isQueryPublicMethods(); this.fields = classBuildItem.isFields(); this.classes = classBuildItem.isClasses(); this.typeReachable = typeReachable;