Skip to content

Avoid ThreadLocals while using VirtualThreads #39696

Open

Description

Similarly to FasterXML/jackson-core#919

in quarkus we have few parts which are still using thread locals

eg running the test https://github.com/franz1981/fortune-benchmark/blob/main/fortune-virtual-thread-postgresql/src/test/java/me/escoffier/fortune/virtual/reactive/postgresql/test/FortuneApiTest.java
adding the parameter -Djdk.traceVirtualThreadLocals=true

should report this stack trace (which ca be used in IDEA stack trace analyzer to fix the issues, one by one):

VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    io.vertx.core.impl.VertxImpl.beginDispatch2(VertxImpl.java:1372)
    io.vertx.core.impl.VertxImpl.beginDispatch(VertxImpl.java:1366)
    io.vertx.core.impl.ContextInternal.beginDispatch(ContextInternal.java:301)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:43)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$IndexNode.keyOf(ZipFileSystem.java:2603)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.getInode(ZipFileSystem.java:1899)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.exists(ZipFileSystem.java:658)
    jdk.zipfs/jdk.nio.zipfs.ZipPath.exists(ZipPath.java:905)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.exists(ZipFileSystemProvider.java:197)
    java.base/java.nio.file.Files.exists(Files.java:2514)
    io.quarkus.paths.DirectoryPathTree.apply(DirectoryPathTree.java:103)
    io.quarkus.paths.ArchivePathTree$OpenArchivePathTree.apply(ArchivePathTree.java:262)
    io.quarkus.paths.PathTreeWithManifest.apply(PathTreeWithManifest.java:74)
    io.quarkus.paths.SharedArchivePathTree$CallerOpenPathTree.apply(SharedArchivePathTree.java:153)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement.lambda$getResource$1(PathTreeClassPathElement.java:106)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement.apply(PathTreeClassPathElement.java:114)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement.getResource(PathTreeClassPathElement.java:106)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:504)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
    io.vertx.core.impl.VertxImpl.beginDispatch2(VertxImpl.java:1377)
    io.vertx.core.impl.VertxImpl.beginDispatch(VertxImpl.java:1366)
    io.vertx.core.impl.ContextInternal.beginDispatch(ContextInternal.java:301)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:43)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.set(ThreadLocal.java:253)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$IndexNode.keyOf(ZipFileSystem.java:2606)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.getInode(ZipFileSystem.java:1899)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.exists(ZipFileSystem.java:658)
    jdk.zipfs/jdk.nio.zipfs.ZipPath.exists(ZipPath.java:905)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.exists(ZipFileSystemProvider.java:197)
    java.base/java.nio.file.Files.exists(Files.java:2514)
    io.quarkus.paths.DirectoryPathTree.apply(DirectoryPathTree.java:103)
    io.quarkus.paths.ArchivePathTree$OpenArchivePathTree.apply(ArchivePathTree.java:262)
    io.quarkus.paths.PathTreeWithManifest.apply(PathTreeWithManifest.java:74)
    io.quarkus.paths.SharedArchivePathTree$CallerOpenPathTree.apply(SharedArchivePathTree.java:153)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement.lambda$getResource$1(PathTreeClassPathElement.java:106)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement.apply(PathTreeClassPathElement.java:114)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement.getResource(PathTreeClassPathElement.java:106)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:504)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
    io.vertx.core.impl.VertxImpl.beginDispatch2(VertxImpl.java:1377)
    io.vertx.core.impl.VertxImpl.beginDispatch(VertxImpl.java:1366)
    io.vertx.core.impl.ContextInternal.beginDispatch(ContextInternal.java:301)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:43)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.getCarrierThreadLocal(ThreadLocal.java:181)
    java.base/java.lang.System$2.getCarrierThreadLocal(System.java:2597)
    java.base/jdk.internal.misc.CarrierThreadLocal.get(CarrierThreadLocal.java:39)
    java.base/jdk.internal.misc.TerminatingThreadLocal.register(TerminatingThreadLocal.java:83)
    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:233)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.getCarrierThreadLocal(ThreadLocal.java:181)
    java.base/java.lang.System$2.getCarrierThreadLocal(System.java:2597)
    java.base/jdk.internal.misc.CarrierThreadLocal.get(CarrierThreadLocal.java:39)
    java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:230)
    java.base/sun.nio.ch.IOUtil.read(IOUtil.java:303)
    java.base/sun.nio.ch.IOUtil.read(IOUtil.java:283)
    java.base/sun.nio.ch.FileChannelImpl.readInternal(FileChannelImpl.java:984)
    java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:967)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.readFullyAt(ZipFileSystem.java:1241)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.readFullyAt(ZipFileSystem.java:1236)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$EntryInputStream.initDataPos(ZipFileSystem.java:2386)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$EntryInputStream.read(ZipFileSystem.java:2328)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$2.fill(ZipFileSystem.java:2278)
    java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:175)
    java.base/java.io.InputStream.readNBytes(InputStream.java:412)
    java.base/java.io.InputStream.readAllBytes(InputStream.java:349)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.newByteChannel(ZipFileSystem.java:977)
    jdk.zipfs/jdk.nio.zipfs.ZipPath.newByteChannel(ZipPath.java:870)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newByteChannel(ZipFileSystemProvider.java:247)
    java.base/java.nio.file.Files.newByteChannel(Files.java:379)
    java.base/java.nio.file.Files.newByteChannel(Files.java:431)
    java.base/java.nio.file.Files.readAllBytes(Files.java:3268)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement$Resource.getData(PathTreeClassPathElement.java:269)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:506)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
    io.vertx.core.impl.VertxImpl.beginDispatch2(VertxImpl.java:1377)
    io.vertx.core.impl.VertxImpl.beginDispatch(VertxImpl.java:1366)
    io.vertx.core.impl.ContextInternal.beginDispatch(ContextInternal.java:301)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:43)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.getCarrierThreadLocal(ThreadLocal.java:181)
    java.base/java.lang.System$2.getCarrierThreadLocal(System.java:2597)
    java.base/jdk.internal.misc.CarrierThreadLocal.get(CarrierThreadLocal.java:39)
    java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:230)
    java.base/sun.nio.ch.IOUtil.read(IOUtil.java:303)
    java.base/sun.nio.ch.IOUtil.read(IOUtil.java:283)
    java.base/sun.nio.ch.FileChannelImpl.readInternal(FileChannelImpl.java:984)
    java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:967)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.readFullyAt(ZipFileSystem.java:1241)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.readFullyAt(ZipFileSystem.java:1236)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$EntryInputStream.initDataPos(ZipFileSystem.java:2386)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$EntryInputStream.read(ZipFileSystem.java:2328)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$2.fill(ZipFileSystem.java:2278)
    java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:175)
    java.base/java.io.InputStream.readNBytes(InputStream.java:412)
    java.base/java.io.InputStream.readAllBytes(InputStream.java:349)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.newByteChannel(ZipFileSystem.java:977)
    jdk.zipfs/jdk.nio.zipfs.ZipPath.newByteChannel(ZipPath.java:870)
    jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newByteChannel(ZipFileSystemProvider.java:247)
    java.base/java.nio.file.Files.newByteChannel(Files.java:379)
    java.base/java.nio.file.Files.newByteChannel(Files.java:431)
    java.base/java.nio.file.Files.readAllBytes(Files.java:3268)
    io.quarkus.bootstrap.classloading.PathTreeClassPathElement$Resource.getData(PathTreeClassPathElement.java:269)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:506)
    io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
    io.vertx.core.impl.VertxImpl.beginDispatch2(VertxImpl.java:1377)
    io.vertx.core.impl.VertxImpl.beginDispatch(VertxImpl.java:1366)
    io.vertx.core.impl.ContextInternal.beginDispatch(ContextInternal.java:301)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:43)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.set(ThreadLocal.java:253)
    io.vertx.core.impl.VertxImpl.beginDispatch2(VertxImpl.java:1378)
    io.vertx.core.impl.VertxImpl.beginDispatch(VertxImpl.java:1366)
    io.vertx.core.impl.ContextInternal.beginDispatch(ContextInternal.java:301)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:43)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    io.quarkus.arc.impl.InjectionPointProvider.set(InjectionPointProvider.java:29)
    io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:556)
    io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:539)
    io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:572)
    io.quarkus.arc.impl.ArcContainerImpl$3.get(ArcContainerImpl.java:331)
    io.quarkus.arc.impl.ArcContainerImpl$3.get(ArcContainerImpl.java:328)
    io.quarkus.arc.runtime.BeanContainerImpl$1.create(BeanContainerImpl.java:58)
    io.quarkus.resteasy.reactive.common.runtime.ArcBeanFactory.createInstance(ArcBeanFactory.java:27)
    org.jboss.resteasy.reactive.server.handlers.InstanceHandler.handle(InstanceHandler.java:26)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:139)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.set(ThreadLocal.java:253)
    io.quarkus.arc.impl.InjectionPointProvider.set(InjectionPointProvider.java:33)
    io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:556)
    io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:539)
    io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:572)
    io.quarkus.arc.impl.ArcContainerImpl$3.get(ArcContainerImpl.java:331)
    io.quarkus.arc.impl.ArcContainerImpl$3.get(ArcContainerImpl.java:328)
    io.quarkus.arc.runtime.BeanContainerImpl$1.create(BeanContainerImpl.java:58)
    io.quarkus.resteasy.reactive.common.runtime.ArcBeanFactory.createInstance(ArcBeanFactory.java:27)
    org.jboss.resteasy.reactive.server.handlers.InstanceHandler.handle(InstanceHandler.java:26)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:139)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    io.smallrye.context.SmallRyeThreadContext.getCurrentThreadContext(SmallRyeThreadContext.java:194)
    io.smallrye.context.SmallRyeThreadContext.getCurrentThreadContextOrDefaultContexts(SmallRyeThreadContext.java:160)
    io.smallrye.mutiny.context.DefaultContextPropagationInterceptor.getThreadContext(DefaultContextPropagationInterceptor.java:12)
    io.smallrye.mutiny.context.BaseContextPropagationInterceptor.decorate(BaseContextPropagationInterceptor.java:33)
    io.smallrye.mutiny.infrastructure.Infrastructure.decorate(Infrastructure.java:152)
    io.smallrye.mutiny.vertx.AsyncResultUni.<init>(AsyncResultUni.java:21)
    io.smallrye.mutiny.vertx.AsyncResultUni.toUni(AsyncResultUni.java:17)
    io.vertx.mutiny.sqlclient.Pool.getConnection(Pool.java:115)
    io.vertx.mutiny.pgclient.PgPool_Ly1M_jXJtinTvrqFDvbMm7TSXGc_Synthetic_ClientProxy.getConnection(Unknown Source)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository.listAll(FortuneRepository.java:53)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository_ClientProxy.listAll(Unknown Source)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource.getAllFortunes(FortuneResource.java:22)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource$quarkusrestinvoker$getAllFortunes_17630c6d41f1fd48ab8b75db07f293217742deee.invoke(Unknown Source)
    org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.set(ThreadLocal.java:253)
    io.smallrye.context.SmallRyeThreadContext.withThreadContext(SmallRyeThreadContext.java:93)
    io.smallrye.context.impl.SlowActiveContextState.<init>(SlowActiveContextState.java:31)
    io.smallrye.context.impl.SlowCapturedContextState.begin(SlowCapturedContextState.java:34)
    io.smallrye.context.impl.SlowCapturedContextState.begin(SlowCapturedContextState.java:13)
    io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:20)
    io.smallrye.mutiny.vertx.AsyncResultUni.subscribe(AsyncResultUni.java:31)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:60)
    io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
    io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository.listAll(FortuneRepository.java:62)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository_ClientProxy.listAll(Unknown Source)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource.getAllFortunes(FortuneResource.java:22)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource$quarkusrestinvoker$getAllFortunes_17630c6d41f1fd48ab8b75db07f293217742deee.invoke(Unknown Source)
    org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    io.netty.util.internal.InternalThreadLocalMap.slowGet(InternalThreadLocalMap.java:130)
    io.netty.util.internal.InternalThreadLocalMap.get(InternalThreadLocalMap.java:117)
    io.netty.util.concurrent.FastThreadLocal.get(FastThreadLocal.java:136)
    io.vertx.core.net.impl.pool.CombinerExecutor.submit(CombinerExecutor.java:85)
    io.vertx.core.net.impl.pool.SimpleConnectionPool.execute(SimpleConnectionPool.java:244)
    io.vertx.core.net.impl.pool.SimpleConnectionPool.acquire(SimpleConnectionPool.java:639)
    io.vertx.sqlclient.impl.pool.SqlConnectionPool.acquire(SqlConnectionPool.java:239)
    io.vertx.sqlclient.impl.PoolImpl.acquire(PoolImpl.java:176)
    io.vertx.sqlclient.impl.PoolImpl.getConnection(PoolImpl.java:139)
    io.vertx.sqlclient.impl.PoolImpl.getConnection(PoolImpl.java:126)
    io.vertx.sqlclient.impl.PoolBase.getConnection(PoolBase.java:56)
    io.vertx.pgclient.PgPool_7weXgYHcaRck_k2l7dGKfXZMdD8_Synthetic_ClientProxy.getConnection(Unknown Source)
    io.vertx.mutiny.sqlclient.Pool.lambda$getConnection$11(Pool.java:116)
    io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
    io.smallrye.mutiny.vertx.AsyncResultUni.subscribe(AsyncResultUni.java:31)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:60)
    io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
    io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository.listAll(FortuneRepository.java:62)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository_ClientProxy.listAll(Unknown Source)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource.getAllFortunes(FortuneResource.java:22)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource$quarkusrestinvoker$getAllFortunes_17630c6d41f1fd48ab8b75db07f293217742deee.invoke(Unknown Source)
    org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.set(ThreadLocal.java:253)
    io.netty.util.internal.InternalThreadLocalMap.slowGet(InternalThreadLocalMap.java:133)
    io.netty.util.internal.InternalThreadLocalMap.get(InternalThreadLocalMap.java:117)
    io.netty.util.concurrent.FastThreadLocal.get(FastThreadLocal.java:136)
    io.vertx.core.net.impl.pool.CombinerExecutor.submit(CombinerExecutor.java:85)
    io.vertx.core.net.impl.pool.SimpleConnectionPool.execute(SimpleConnectionPool.java:244)
    io.vertx.core.net.impl.pool.SimpleConnectionPool.acquire(SimpleConnectionPool.java:639)
    io.vertx.sqlclient.impl.pool.SqlConnectionPool.acquire(SqlConnectionPool.java:239)
    io.vertx.sqlclient.impl.PoolImpl.acquire(PoolImpl.java:176)
    io.vertx.sqlclient.impl.PoolImpl.getConnection(PoolImpl.java:139)
    io.vertx.sqlclient.impl.PoolImpl.getConnection(PoolImpl.java:126)
    io.vertx.sqlclient.impl.PoolBase.getConnection(PoolBase.java:56)
    io.vertx.pgclient.PgPool_7weXgYHcaRck_k2l7dGKfXZMdD8_Synthetic_ClientProxy.getConnection(Unknown Source)
    io.vertx.mutiny.sqlclient.Pool.lambda$getConnection$11(Pool.java:116)
    io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
    io.smallrye.mutiny.vertx.AsyncResultUni.subscribe(AsyncResultUni.java:31)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:60)
    io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
    io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository.listAll(FortuneRepository.java:62)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository_ClientProxy.listAll(Unknown Source)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource.getAllFortunes(FortuneResource.java:22)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource$quarkusrestinvoker$getAllFortunes_17630c6d41f1fd48ab8b75db07f293217742deee.invoke(Unknown Source)
    org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)
VirtualThread[#172,quarkus-virtual-thread-0]/runnable@ForkJoinPool-1-worker-1    java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:236)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:194)
    java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172)
    com.intellij.rt.debugger.agent.CaptureStorage.capture(CaptureStorage.java:43)
    io.netty.util.concurrent.SingleThreadEventExecutor.execute0(SingleThreadEventExecutor.java)
    io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:817)
    io.netty.util.concurrent.AbstractScheduledEventExecutor.schedule(AbstractScheduledEventExecutor.java:290)
    io.netty.util.concurrent.AbstractScheduledEventExecutor.schedule(AbstractScheduledEventExecutor.java:205)
    io.vertx.core.impl.VertxImpl.scheduleTimeout(VertxImpl.java:667)
    io.vertx.core.impl.VertxImpl.scheduleTimeout(VertxImpl.java:678)
    io.vertx.core.impl.ContextInternal.setTimer(ContextInternal.java:478)
    io.vertx.sqlclient.impl.pool.SqlConnectionPool$1PoolRequest.onEnqueue(SqlConnectionPool.java:219)
    io.vertx.sqlclient.impl.pool.SqlConnectionPool$1PoolRequest.onConnect(SqlConnectionPool.java:235)
    io.vertx.core.net.impl.pool.SimpleConnectionPool$Acquire$3.run(SimpleConnectionPool.java:593)
    io.vertx.core.net.impl.pool.Task.runNextTasks(Task.java:43)
    io.vertx.core.net.impl.pool.CombinerExecutor.submit(CombinerExecutor.java:91)
    io.vertx.core.net.impl.pool.SimpleConnectionPool.execute(SimpleConnectionPool.java:244)
    io.vertx.core.net.impl.pool.SimpleConnectionPool.acquire(SimpleConnectionPool.java:639)
    io.vertx.sqlclient.impl.pool.SqlConnectionPool.acquire(SqlConnectionPool.java:239)
    io.vertx.sqlclient.impl.PoolImpl.acquire(PoolImpl.java:176)
    io.vertx.sqlclient.impl.PoolImpl.getConnection(PoolImpl.java:139)
    io.vertx.sqlclient.impl.PoolImpl.getConnection(PoolImpl.java:126)
    io.vertx.sqlclient.impl.PoolBase.getConnection(PoolBase.java:56)
    io.vertx.pgclient.PgPool_7weXgYHcaRck_k2l7dGKfXZMdD8_Synthetic_ClientProxy.getConnection(Unknown Source)
    io.vertx.mutiny.sqlclient.Pool.lambda$getConnection$11(Pool.java:116)
    io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
    io.smallrye.mutiny.vertx.AsyncResultUni.subscribe(AsyncResultUni.java:31)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)
    io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
    io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:60)
    io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
    io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository.listAll(FortuneRepository.java:62)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneRepository_ClientProxy.listAll(Unknown Source)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource.getAllFortunes(FortuneResource.java:22)
    me.escoffier.fortune.virtual.reactive.postgresql.FortuneResource$quarkusrestinvoker$getAllFortunes_17630c6d41f1fd48ab8b75db07f293217742deee.invoke(Unknown Source)
    org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
    java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    java.base/java.lang.VirtualThread.run(VirtualThread.java:311)

I think JDK 21 have a BUG on the mentioned property, because the stacks which contains

java.base/java.lang.ThreadLocal.getCarrierThreadLocal(ThreadLocal.java:181)

are absolutely fine.
This is a sign that most users didn't used this feature to make sure are not using thread locals on virtual thread(s) OR that loom is not that used (yet, which makes sense) OR that thread local(s) is not widely used (which is unlikely, really).

Instead, https://github.com/openjdk/jdk/blob/b9c76dedf4aa2248a5e561a535c9e3e181f7836a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java#L2799 shows that OpenJDK still have to fix its own ThreadLocal usages as well, although, is not a big deal per-se, given that the number of class-loading operations should not keep on increasing during a run, in theory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    area/virtual-threadsIssue related to Java's Virtual Threadskind/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions