Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sub-Sub resources not supported in reactive rest client #22055

Closed
lordvlad opened this issue Dec 9, 2021 · 6 comments · Fixed by #22417
Closed

Sub-Sub resources not supported in reactive rest client #22055

lordvlad opened this issue Dec 9, 2021 · 6 comments · Fixed by #22417
Labels
area/rest-client kind/bug Something isn't working
Milestone

Comments

@lordvlad
Copy link
Contributor

lordvlad commented Dec 9, 2021

Describe the bug

When using reactive rest clients, defining sub sub (sub sub sub, ...) resources does not work. I can defined them, but on access, an AbstractMethodError is thrown.

Expected behavior

I can define an arbitrary hierary of resources and subresources

Actual behavior

I can only define a single level of subresources. Accessing any further sub levels will result in an AbstractMethodError.

How to Reproduce?

I've extended the test case in the quarkus repo to showcase the behavior: 2.5.1.Final...lordvlad:subsubresource-bug-reproducer

Output of uname -a or ver

Linux son-nb-wru-01 5.11.0-41-generic #45~20.04.1-Ubuntu SMP Wed Nov 10 10:20:10 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.5.1.Final

Build tool (ie. output of mvnw --version or gradlew --version)

gradle 7.0

Additional information

works with quarkus-rest-client

Stack trace

ERROR] Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 3.671 s <<< FAILURE! - in io.quarkus.rest.client.reactive.subresource.SubResourceTest
[ERROR] io.quarkus.rest.client.reactive.subresource.SubResourceTest.shouldDoMultiplePosts  Time elapsed: 0.035 s  <<< ERROR!
java.lang.AbstractMethodError: Receiver class io.quarkus.rest.client.reactive.subresource.SubResourceTest$SubCliented77e297b94a7e0aa21c1f7f1d8ba4fbe72d61861 does not define or inherit an implementation of the resolved method 'abstract io.quarkus.rest.client.reactive.subresource.SubResourceTest$SubSubClient sub(java.lang.String, java.lang.String)' of interface io.quarkus.rest.client.reactive.subresource.SubResourceTest$SubClient.
	at io.quarkus.rest.client.reactive.subresource.SubResourceTest.shouldDoMultiplePosts(SubResourceTest.java:73)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at io.quarkus.test.QuarkusUnitTest.runExtensionMethod(QuarkusUnitTest.java:420)
	at io.quarkus.test.QuarkusUnitTest.interceptTestMethod(QuarkusUnitTest.java:388)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:188)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:154)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:128)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)

@lordvlad lordvlad added the kind/bug Something isn't working label Dec 9, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Dec 9, 2021

/cc @michalszynkiewicz

@geoand
Copy link
Contributor

geoand commented Dec 9, 2021

Also cc @Sgitario in case this is something you would like to look into

@Sgitario
Copy link
Contributor

Sgitario commented Dec 9, 2021

Also cc @Sgitario in case this is something you would like to look into

+1

@Sgitario
Copy link
Contributor

I've been looking into fixing this issue and at the moment and current solution does not support clients hierarchy as it's based on constructors which are not accessible from sub sub resources.
In order to move forward, @michalszynkiewicz will refactor the solution and clean up the final generated clients (probably for next year). Afterwards, I will revisit this issue.

Sgitario added a commit to Sgitario/quarkus that referenced this issue Dec 20, 2021
Allow to use sub resources in client resources:

Usage for first level:
```java
@path("/path")
@RegisterRestClient(baseUri = "http://localhost:8081")
@consumes("text/plain")
@produces("text/plain")
public interface RootResource {

    @path("/sub")
    SubClient sub();
}
```

Second level:
```
@consumes("text/plain")
@produces("text/plain")
interface SubClient {
    @path("/sub")
    SubSubClient sub();
}
```

Third and N levels (this was unsupported and now it's supported):
```
@consumes("text/plain")
@produces("text/plain")
interface SubSubClient {
    @get
    @path("/simple")
    String simpleGet();
}
```

Fix quarkusio#22055
@Sgitario
Copy link
Contributor

@michalszynkiewicz finally I found a solution which works fine and requires only a few changes.

Sgitario added a commit to Sgitario/quarkus that referenced this issue Dec 20, 2021
Allow to use sub resources in client resources:

Usage for first level:
```java
@path("/path")
@RegisterRestClient(baseUri = "http://localhost:8081")
@consumes("text/plain")
@produces("text/plain")
public interface RootResource {

    @path("/sub")
    SubClient sub();
}
```

Second level:
```
@consumes("text/plain")
@produces("text/plain")
interface SubClient {
    @path("/sub")
    SubSubClient sub();
}
```

Third and N levels (this was unsupported and now it's supported):
```
@consumes("text/plain")
@produces("text/plain")
interface SubSubClient {
    @get
    @path("/simple")
    String simpleGet();
}
```

Fix quarkusio#22055
Sgitario added a commit to Sgitario/quarkus that referenced this issue Dec 21, 2021
Allow to use sub resources in client resources:

Usage for first level:
```java
@path("/path")
@RegisterRestClient(baseUri = "http://localhost:8081")
@consumes("text/plain")
@produces("text/plain")
public interface RootResource {

    @path("/sub")
    SubClient sub();
}
```

Second level:
```
@consumes("text/plain")
@produces("text/plain")
interface SubClient {
    @path("/sub")
    SubSubClient sub();
}
```

Third and N levels (this was unsupported and now it's supported):
```
@consumes("text/plain")
@produces("text/plain")
interface SubSubClient {
    @get
    @path("/simple")
    String simpleGet();
}
```

Fix quarkusio#22055
Sgitario added a commit to Sgitario/quarkus that referenced this issue Dec 21, 2021
Allow to use sub resources in client resources:

Usage for first level:
```java
@path("/path")
@RegisterRestClient(baseUri = "http://localhost:8081")
@consumes("text/plain")
@produces("text/plain")
public interface RootResource {

    @path("/sub")
    SubClient sub();
}
```

Second level:
```
@consumes("text/plain")
@produces("text/plain")
interface SubClient {
    @path("/sub")
    SubSubClient sub();
}
```

Third and N levels (this was unsupported and now it's supported):
```
@consumes("text/plain")
@produces("text/plain")
interface SubSubClient {
    @get
    @path("/simple")
    String simpleGet();
}
```

Fix quarkusio#22055
@quarkus-bot quarkus-bot bot added this to the 2.7 - main milestone Dec 21, 2021
@lordvlad
Copy link
Contributor Author

Hi! Quick question on the release process. So the issue has been fixed, but the bot assigned it to milestone 2.7. Is there any chance this might be rather included in one of the 2.6 patch releases? If not, is there a timeline for 2.7?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/rest-client kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants