quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.82k stars 2.69k forks source link

Rest Client throws ClassNotFoundException when using parallel stream #44542

Closed Szaraq closed 2 hours ago

Szaraq commented 2 hours ago

Describe the bug

When trying to use RestClient and deserialize the response to POJO in parallel stream, after several successful operations, it throws java.lang.ClassNotFoundException.

Expected behavior

POJO should be deserialized successfully in each parallel stream execution

Actual behavior

After several successful operations of deserialization of POJO in parallel stream, it throws java.lang.ClassNotFoundException on POJO class.

How to Reproduce?

  1. Checkout following repository: https://bitbucket.org/osiczyn/quarkus-bug/src/master/
  2. Deploy application to GCP cloud as cloud run function with pub/sub trigger (not tested locally, but it might be possible to reproduce there as well) - deploy.bat script in repository might be helpful here
  3. Trigger cloud run function using pub/sub
  4. Check cloud run functions for: java.lang.ClassNotFoundException: pl.osik.mtg.tools.preview.importing.dto.CardsDTO after several successful "Fetched: ..." logs

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

3.16.3

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

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937) Maven home: C:\Users\micha.m2\wrapper\dists\apache-maven-3.9.9-bin\33b4b2b4\apache-maven-3.9.9 Java version: 21.0.2, vendor: GraalVM Community, runtime: C:\Users\micha.jdks\graalvm-ce-21.0.2 Default locale: pl_PL, platform encoding: UTF-8 OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

Additional information

No response

quarkus-bot[bot] commented 2 hours ago

/cc @cescoffier (rest-client), @geoand (rest-client)

geoand commented 2 hours ago

Parallel streams should never be used for IO operations.

The reason you are seeing is because the thread pool that is used does not have the proper Thread Context Classloader

geoand commented 2 hours ago

You could manually capture it before the stream starts and set it before the rest client call, but it's just much better to not use parallel streams at all for this kind of thing