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

ClassCastException with RESTEasy reactive and a Jersey client #36024

Closed
jmini opened this issue Sep 20, 2023 · 5 comments · Fixed by #36025
Closed

ClassCastException with RESTEasy reactive and a Jersey client #36024

jmini opened this issue Sep 20, 2023 · 5 comments · Fixed by #36025
Labels
area/rest kind/bug Something isn't working
Milestone

Comments

@jmini
Copy link
Contributor

jmini commented Sep 20, 2023

Describe the bug

A quarkus app with endpoints using RESTEasy reactive using the org.jboss.resteasy.reactive.ResponseStatus annotation and a Jersey client is not working.

Expected behavior

Can this be supported?

If yes, it would be nice if adding the Jersey client would not impact the quarkus part.

Actual behavior

When the endpoint is called:

ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /hello failed, error id: b4f7ffaf-b82e-4550-802e-1244e1f8aceb-1: java.lang.ClassCastException: class org.glassfish.jersey.message.internal.OutboundJaxrsResponse$Builder cannot be cast to class org.jboss.resteasy.reactive.server.jaxrs.ResponseBuilderImpl (org.glassfish.jersey.message.internal.OutboundJaxrsResponse$Builder and org.jboss.resteasy.reactive.server.jaxrs.ResponseBuilderImpl are in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @aecb35a)
        at org.jboss.resteasy.reactive.server.handlers.ResponseHandler$1.get(ResponseHandler.java:155)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.encodeResponseHeaders(ServerSerialisers.java:503)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers$1.accept(ServerSerialisers.java:77)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers$1.accept(ServerSerialisers.java:74)
        at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext.handle(VertxResteasyReactiveRequestContext.java:468)
        at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext.handle(VertxResteasyReactiveRequestContext.java:45)
        at io.vertx.ext.web.impl.RoutingContextImpl.lambda$null$0(RoutingContextImpl.java:495)
        at io.vertx.ext.web.impl.SparseArray.forEachInReverseOrder(SparseArray.java:41)
        at io.vertx.ext.web.impl.RoutingContextImpl.lambda$getHeadersEndHandlers$1(RoutingContextImpl.java:495)
        at io.vertx.core.http.impl.Http1xServerResponse.prepareHeaders(Http1xServerResponse.java:732)
        at io.vertx.core.http.impl.Http1xServerResponse.end(Http1xServerResponse.java:430)
        at io.vertx.core.http.impl.Http1xServerResponse.end(Http1xServerResponse.java:415)
        at org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext.end(VertxResteasyReactiveRequestContext.java:370)
        at org.jboss.resteasy.reactive.server.providers.serialisers.ServerStringMessageBodyHandler.writeResponse(ServerStringMessageBodyHandler.java:26)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:227)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:195)
        at org.jboss.resteasy.reactive.server.core.serialization.FixedEntityWriter.write(FixedEntityWriter.java:28)
        at org.jboss.resteasy.reactive.server.handlers.ResponseWriterHandler.handle(ResponseWriterHandler.java:34)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:147)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:577)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:833)

How to Reproduce?

Step to reproduce:

  1. Create a project with resteasy-reactive link on code.quarkus.io to create the project.
  2. Add @ResponseStatus(201) on the hello endpoint
  3. Add an implementation org.glassfish.jersey.core:jersey-common:3.1.3 dependency (in my real project I add a java REST client that has library as dependency)
  4. Call the endpoint curl http://localhost:8080/hello

Output of uname -a or ver

Darwin 22.3.0 Darwin Kernel Version 22.3.0: Mon Jan 30 20:42:11 PST 2023; root:xnu-8792.81.3~2/RELEASE_X86_64 x86_64

Output of java -version

openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode, sharing)

Quarkus version or git rev

3.3.3

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

------------------------------------------------------------
Gradle 8.1.1
------------------------------------------------------------

Build time:   2023-04-21 12:31:26 UTC
Revision:     1cf537a851c635c364a4214885f8b9798051175b

Kotlin:       1.8.10
Groovy:       3.0.15
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          17.0.5 (Eclipse Adoptium 17.0.5+8)
OS:           Mac OS X 13.2.1 x86_64

Additional information

Reproducer project https://github.com/jmini/quarkus-experiments/tree/main/quarkus_issue36024

@jmini jmini added the kind/bug Something isn't working label Sep 20, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Sep 20, 2023

/cc @FroMage (resteasy-reactive), @evanchooly (kotlin), @geoand (kotlin,resteasy-reactive), @stuartwdouglas (resteasy-reactive)

@geoand
Copy link
Contributor

geoand commented Sep 20, 2023

You can't use the Jersey client with RESTEasy Reactive. You either use our implementatio of the JAX-RS client (quarkus-jaxrs-client-reactive) or our implemenation of the Microprofile REST Client (quarkus-rest-client-reactive).

@geoand geoand closed this as not planned Won't fix, can't repro, duplicate, stale Sep 20, 2023
@geoand geoand added triage/wontfix This will not be worked on and removed area/kotlin labels Sep 20, 2023
jmini added a commit to jmini/quarkus-experiments that referenced this issue Sep 20, 2023
@jmini
Copy link
Contributor Author

jmini commented Sep 20, 2023

@geoand thank you for the quick confirmation. I already thought this would be the case, but it is not written in the documentation.


If the Jersey part is something that I can change. The client library already exists (and is not something I can change) and is embedding Jersey jars as transitive dependencies.

What are my options at quarkus level?
Use reative-routes to write the endpoint?


An other check I could do is to verify if the client is really relying on Jersey, or if they are just using the JAX-RS api. In that case I might be able to exchange the lib implementing the JAX-RS API.
Not sure this would work 🤔...


This topic of the embedded java HTTP clients is really something that make me think a lot. I started this discussion: How to write a REST client library that is framework agnostic but never got any answer.

@geoand
Copy link
Contributor

geoand commented Sep 20, 2023

It turns out that starting Quarkus 3.4.0 your use case works somewhat better (thank to #35558), but I'll reopen the issue and see if things can be improved further.

Now WRT framework agnostic clients, I like what Fabric8 Kubernetes Client, Testcontainers and OpenTelemetry have done: That is to create an SPI and then have various implementations (like OkHttp, JDK HttpClient, Vert.x etc).
That also allows a framework like Quarkus to even plug in its own implementation.

@geoand geoand reopened this Sep 20, 2023
@geoand geoand removed the triage/wontfix This will not be worked on label Sep 20, 2023
jmini added a commit to jmini/quarkus-experiments that referenced this issue Sep 20, 2023
geoand added a commit to geoand/quarkus that referenced this issue Sep 20, 2023
This is needed in order to avoid getting CCE
when other implementations of Jakarta REST are
on the classpath

Closes: quarkusio#36024
@geoand
Copy link
Contributor

geoand commented Sep 20, 2023

#36025 fixes your issue.

geoand added a commit that referenced this issue Sep 20, 2023
Don't use RuntimeDelegate in ResponseHandler
@quarkus-bot quarkus-bot bot added this to the 3.5 - main milestone Sep 20, 2023
@gsmet gsmet modified the milestones: 3.5 - main, 3.4.2 Oct 3, 2023
gsmet pushed a commit to gsmet/quarkus that referenced this issue Oct 3, 2023
This is needed in order to avoid getting CCE
when other implementations of Jakarta REST are
on the classpath

Closes: quarkusio#36024
(cherry picked from commit c636df6)
@aloubyansky aloubyansky modified the milestones: 3.4.2, 3.2.8.Final Oct 31, 2023
aloubyansky pushed a commit to aloubyansky/quarkus that referenced this issue Oct 31, 2023
This is needed in order to avoid getting CCE
when other implementations of Jakarta REST are
on the classpath

Closes: quarkusio#36024
(cherry picked from commit c636df6)
holly-cummins pushed a commit to holly-cummins/quarkus that referenced this issue Feb 8, 2024
This is needed in order to avoid getting CCE
when other implementations of Jakarta REST are
on the classpath

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

Successfully merging a pull request may close this issue.

4 participants