Skip to content

Commit 99672c2

Browse files
committed
Execution Model Validation: properly discover Dev UI JSON RPC classes
The `JsonRPCProvidersBuildItem` often used to be produced only in dev mode (but note that some extensions produce it always already). This disallowed using this build item to discover Dev UI JSON RPC classes properly, so we used to ship a gross hack in the execution model annotation validation. It is time to fix that. The `JsonRPCProvidersBuildItem` is always produced, so we can rely on it for discovering all the Dev UI JSON RPC classes.
1 parent ec22a12 commit 99672c2

File tree

34 files changed

+112
-46
lines changed

34 files changed

+112
-46
lines changed

core/deployment/src/main/java/io/quarkus/deployment/execannotations/ExecutionModelAnnotationsProcessor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ private void doCheck(StringBuilder message, IndexView index,
8686
}
8787
}
8888

89+
/**
90+
* @deprecated this method will be removed in Quarkus 3.24, which gives extensions 2 releases
91+
* to start producing {@code JsonRPCProvidersBuildItem} always, not just in dev mode
92+
*/
93+
@Deprecated(since = "3.22", forRemoval = true)
8994
@BuildStep
9095
ExecutionModelAnnotationsAllowedBuildItem devuiJsonRpcServices() {
9196
return new ExecutionModelAnnotationsAllowedBuildItem(new Predicate<MethodInfo>() {

docs/src/main/asciidoc/dev-ui.adoc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -876,14 +876,13 @@ You must register the `JsonPRCService` in your processor in the deployment modul
876876

877877
[source,java]
878878
----
879-
@BuildStep(onlyIf = IsDevelopment.class)// <1>
880-
JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {// <2>
881-
return new JsonRPCProvidersBuildItem(CacheJsonRPCService.class);// <3>
879+
@BuildStep
880+
JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {// <1>
881+
return new JsonRPCProvidersBuildItem(CacheJsonRPCService.class);// <2>
882882
}
883883
----
884-
<1> Always only do this in Dev Mode
885-
<2> Produce or return a `JsonRPCProvidersBuildItem`
886-
<3> Define the class in your runtime module that will contain methods that make data available in the UI
884+
<1> Produce or return a `JsonRPCProvidersBuildItem`
885+
<2> Define the class in your runtime module that will contain methods that make data available in the UI
887886

888887
https://github.com/quarkusio/quarkus/blob/main/extensions/cache/deployment/src/main/java/io/quarkus/cache/deployment/devui/CacheDevUiProcessor.java[Example code]
889888

extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/devui/AgroalDevUIProcessor.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class AgroalDevUIProcessor {
1818
@BuildStep
1919
void devUI(DataSourcesJdbcBuildTimeConfig config,
2020
BuildProducer<CardPageBuildItem> cardPageProducer,
21-
BuildProducer<JsonRPCProvidersBuildItem> jsonRPCProviderProducer,
2221
LaunchModeBuildItem launchMode) {
2322

2423
if (launchMode.getDevModeType().isPresent() && launchMode.getDevModeType().get().equals(DevModeType.LOCAL)) {
@@ -34,8 +33,12 @@ void devUI(DataSourcesJdbcBuildTimeConfig config,
3433
.metadata("allowedHost", config.devui().allowedDBHost().orElse(null)));
3534

3635
cardPageProducer.produce(cardPageBuildItem);
37-
jsonRPCProviderProducer.produce(new JsonRPCProvidersBuildItem(DatabaseInspector.class));
3836
}
3937
}
4038
}
39+
40+
@BuildStep
41+
JsonRPCProvidersBuildItem createJsonRPCService() {
42+
return new JsonRPCProvidersBuildItem(DatabaseInspector.class);
43+
}
4144
}

extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/devui/ArcDevUIProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public CardPageBuildItem pages(ArcBeanInfoBuildItem arcBeanInfoBuildItem, ArcCon
102102
return pageBuildItem;
103103
}
104104

105-
@BuildStep(onlyIf = IsDevelopment.class)
105+
@BuildStep
106106
JsonRPCProvidersBuildItem createJsonRPCService() {
107107
return new JsonRPCProvidersBuildItem(ArcJsonRPCService.class);
108108
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.quarkus.arc.deployment.devui;
2+
3+
import java.util.HashSet;
4+
import java.util.List;
5+
import java.util.Set;
6+
import java.util.function.Predicate;
7+
8+
import org.jboss.jandex.MethodInfo;
9+
10+
import io.quarkus.deployment.annotations.BuildStep;
11+
import io.quarkus.deployment.execannotations.ExecutionModelAnnotationsAllowedBuildItem;
12+
import io.quarkus.devui.spi.JsonRPCProvidersBuildItem;
13+
14+
// this class is present in the `arc/deployment` module, because it has to be present always
15+
// and cannot be in the `core/deployment` module, as it depends on `quarkus-vertx-http-dev-ui-spi`
16+
public class JsonRpcMethodsProcessor {
17+
@BuildStep
18+
ExecutionModelAnnotationsAllowedBuildItem jsonRpcMethods(List<JsonRPCProvidersBuildItem> rpcProviders) {
19+
Set<String> classes = new HashSet<>();
20+
for (JsonRPCProvidersBuildItem rpcProvider : rpcProviders) {
21+
classes.add(rpcProvider.getJsonRPCMethodProviderClass().getName());
22+
}
23+
24+
return new ExecutionModelAnnotationsAllowedBuildItem(new Predicate<MethodInfo>() {
25+
@Override
26+
public boolean test(MethodInfo method) {
27+
return classes.contains(method.declaringClass().name().toString());
28+
}
29+
});
30+
}
31+
}

extensions/cache/deployment/src/main/java/io/quarkus/cache/deployment/devui/CacheDevUiProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ CardPageBuildItem create(CurateOutcomeBuildItem bi) {
2121
return pageBuildItem;
2222
}
2323

24-
@BuildStep(onlyIf = IsDevelopment.class)
24+
@BuildStep
2525
JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {
2626
return new JsonRPCProvidersBuildItem(CacheJsonRPCService.class);
2727
}

extensions/container-image/deployment/src/main/java/io/quarkus/container/image/deployment/devui/ContainerImageDevUiProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ CardPageBuildItem create(List<AvailableContainerImageExtensionBuildItem> extensi
3737
return card;
3838
}
3939

40-
@BuildStep(onlyIf = IsDevelopment.class)
40+
@BuildStep
4141
JsonRPCProvidersBuildItem createJsonRPCServiceForContainerBuild() {
4242
DevConsoleManager.register("container-image-build-action", build());
4343
return new JsonRPCProvidersBuildItem(ContainerBuilderJsonRpcService.class);

extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devui/DevUIDatasourceProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ CardPageBuildItem create(DataSourcesBuildTimeConfig dataSourceBuildTimeConfig) {
3030
return card;
3131
}
3232

33-
@BuildStep(onlyIf = IsDevelopment.class)
33+
@BuildStep
3434
JsonRPCProvidersBuildItem registerJsonRpcBackend() {
3535
return new JsonRPCProvidersBuildItem(DatasourceJsonRpcService.class);
3636
}

extensions/flyway/deployment/src/main/java/io/quarkus/flyway/deployment/devui/FlywayDevUIProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ CardPageBuildItem create(FlywayDevUIRecorder recorder, FlywayBuildTimeConfig bui
4545
return card;
4646
}
4747

48-
@BuildStep(onlyIf = IsDevelopment.class)
48+
@BuildStep
4949
JsonRPCProvidersBuildItem registerJsonRpcBackend() {
5050
return new JsonRPCProvidersBuildItem(FlywayJsonRpcService.class);
5151
}

extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/GrpcMethodsProcessor.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,35 @@
22

33
import java.util.function.Predicate;
44

5+
import org.jboss.jandex.ClassInfo;
6+
import org.jboss.jandex.IndexView;
57
import org.jboss.jandex.MethodInfo;
68

79
import io.quarkus.deployment.annotations.BuildStep;
10+
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
811
import io.quarkus.deployment.execannotations.ExecutionModelAnnotationsAllowedBuildItem;
912

1013
public class GrpcMethodsProcessor {
1114
@BuildStep
12-
ExecutionModelAnnotationsAllowedBuildItem grpcMethods() {
15+
ExecutionModelAnnotationsAllowedBuildItem grpcMethods(CombinedIndexBuildItem combinedIndex) {
16+
IndexView index = combinedIndex.getIndex();
17+
1318
return new ExecutionModelAnnotationsAllowedBuildItem(new Predicate<MethodInfo>() {
1419
@Override
1520
public boolean test(MethodInfo method) {
16-
return method.declaringClass().hasDeclaredAnnotation(GrpcDotNames.GRPC_SERVICE);
21+
// either the method is on a `@GrpcService` class
22+
if (method.declaringClass().hasDeclaredAnnotation(GrpcDotNames.GRPC_SERVICE)) {
23+
return true;
24+
}
25+
26+
// or the method is inherited by a `@GrpcService` class
27+
for (ClassInfo subclass : index.getAllKnownSubclasses(method.declaringClass().name())) {
28+
if (subclass.hasDeclaredAnnotation(GrpcDotNames.GRPC_SERVICE)) {
29+
return true;
30+
}
31+
}
32+
33+
return false;
1734
}
1835
});
1936
}

0 commit comments

Comments
 (0)