Skip to content

Commit f0ff3d7

Browse files
authored
Merge pull request quarkusio#50325 from geoand/quarkusio#50314
Fix issue with multiple generated REST invokers
2 parents 04ffd18 + 5533421 commit f0ff3d7

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/QuarkusInvokerFactory.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import java.lang.reflect.Modifier;
66
import java.util.ArrayList;
77
import java.util.Arrays;
8+
import java.util.HashMap;
89
import java.util.List;
10+
import java.util.Map;
911
import java.util.function.Predicate;
1012
import java.util.function.Supplier;
1113

@@ -32,6 +34,8 @@ public class QuarkusInvokerFactory implements EndpointInvokerFactory {
3234
final BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer;
3335
final ResteasyReactiveRecorder recorder;
3436

37+
private final Map<String, Supplier<EndpointInvoker>> generatedInvokers = new HashMap<>();
38+
3539
public QuarkusInvokerFactory(Predicate<String> applicationClassPredicate,
3640
BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer,
3741
ResteasyReactiveRecorder recorder) {
@@ -51,6 +55,9 @@ public Supplier<EndpointInvoker> create(ResourceMethod method, ClassInfo current
5155

5256
String baseName = currentClassInfo.name() + "$quarkusrestinvoker$" + method.getName() + "_"
5357
+ HashUtil.sha1(endpointIdentifier);
58+
if (generatedInvokers.containsKey(baseName)) {
59+
return generatedInvokers.get(baseName);
60+
}
5461
ClassOutput classOutput = new GeneratedClassGizmo2Adaptor(generatedClassBuildItemBuildProducer, null,
5562
applicationClassPredicate.test(currentClassInfo.name().toString()));
5663
Gizmo g = Gizmo.create(classOutput);
@@ -80,7 +87,9 @@ public Supplier<EndpointInvoker> create(ResourceMethod method, ClassInfo current
8087
});
8188
});
8289
});
83-
return recorder.invoker(baseName);
90+
var result = recorder.invoker(baseName);
91+
generatedInvokers.put(baseName, result);
92+
return result;
8493
}
8594

8695
}

integration-tests/rest-client-reactive-http2/pom.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
<artifactId>vertx-web-client</artifactId>
4444
<scope>test</scope>
4545
</dependency>
46+
<dependency>
47+
<groupId>io.quarkus</groupId>
48+
<artifactId>quarkus-junit5-internal</artifactId>
49+
<scope>test</scope>
50+
</dependency>
4651

4752
<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
4853
<dependency>
@@ -86,6 +91,30 @@
8691
</execution>
8792
</executions>
8893
</plugin>
94+
<plugin>
95+
<groupId>org.apache.maven.plugins</groupId>
96+
<artifactId>maven-surefire-plugin</artifactId>
97+
<configuration>
98+
<runOrder>alphabetical</runOrder>
99+
</configuration>
100+
<executions>
101+
<!--
102+
The prod mode tests need to be part of a different execution to ensure that they don't mess with the standard tests.
103+
By adding this configuration we ensure that the maven surefire plugin will execute twice, one for the regular **/*Test.java
104+
tests (using the 'default-test' execution), and one for the prod mode tests (this 'prod-mode' execution)
105+
-->
106+
<execution>
107+
<id>prod-mode</id>
108+
<phase>test</phase>
109+
<goals>
110+
<goal>test</goal>
111+
</goals>
112+
<configuration>
113+
<includes>**/*PMT.java</includes>
114+
</configuration>
115+
</execution>
116+
</executions>
117+
</plugin>
89118
</plugins>
90119
</build>
91120

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.quarkus.it.rest.client.http2;
2+
3+
import static io.restassured.RestAssured.get;
4+
5+
import jakarta.ws.rs.GET;
6+
import jakarta.ws.rs.Path;
7+
import jakarta.ws.rs.Produces;
8+
import jakarta.ws.rs.core.MediaType;
9+
10+
import org.eclipse.microprofile.rest.client.inject.RestClient;
11+
import org.hamcrest.Matchers;
12+
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.api.extension.RegisterExtension;
14+
15+
import io.quarkus.test.QuarkusProdModeTest;
16+
17+
/**
18+
* This test does not really belong here, but the only way to create a test for
19+
* <a href="https://github.com/quarkusio/quarkus/issues/50314">this issue</a>
20+
* is to build a similar REST application in prod mode.
21+
*/
22+
public class RestMethodInAbstractPMT {
23+
24+
@RegisterExtension
25+
static QuarkusProdModeTest runner = new QuarkusProdModeTest()
26+
.withApplicationRoot((jar) -> jar
27+
.addClasses(BaseResource.class, Resource1.class, Resource2.class, Client.class))
28+
.setRun(true);
29+
30+
@Test
31+
public void test() {
32+
get("/res1")
33+
.then()
34+
.statusCode(200)
35+
.body(Matchers.equalTo("foo"));
36+
}
37+
38+
public static abstract class BaseResource {
39+
40+
@GET
41+
@Path("/base")
42+
@Produces(MediaType.TEXT_PLAIN)
43+
public String base() {
44+
return "base";
45+
}
46+
}
47+
48+
@Path("res1")
49+
public static class Resource1 extends BaseResource {
50+
51+
@GET
52+
public String foo() {
53+
return "foo";
54+
}
55+
}
56+
57+
@Path("res2")
58+
public static class Resource2 extends BaseResource {
59+
60+
@RestClient
61+
Client client;
62+
63+
@GET
64+
public String foo() {
65+
return "foo";
66+
}
67+
68+
@GET
69+
@Path("bar")
70+
public String bar() {
71+
return "bar";
72+
}
73+
}
74+
75+
}

0 commit comments

Comments
 (0)