quarkus: Using Caffeine cach with RequestScoped bean can lead to error

Describe the bug

In a application using @Cache annotation on a a method with Principal parameter, exception occures with the following message :

2022-10-21 16:13:31,935 SEVERE [com.git.ben.caf.cac.BoundedLocalCache] (ForkJoinPool.commonPool-worker-13) Exception thrown when performing the maintenance task: javax.enterprise.context.ContextNotActiveException: RequestScoped context was not active when trying to obtain a bean instance for a client proxy of PRODUCER_METHOD bean [class=io.quarkus.oidc.runtime.OidcJsonWebTokenProducer, id=08f8ad3807046c8f7a5d15c697e2f86e06a9bf82]
	- you can activate the request context for a specific method using the @ActivateRequestContext interceptor binding
	at io.quarkus.arc.impl.ClientProxies.getDelegate(ClientProxies.java:55)
	at org.eclipse.microprofile.jwt.OidcJsonWebTokenProducer_ProducerMethod_currentAccessToken_6cc9acf87bb9cb50add3593d880ba325b4a9f587_ClientProxy.arc$delegate(Unknown Source)
	at org.eclipse.microprofile.jwt.OidcJsonWebTokenProducer_ProducerMethod_currentAccessToken_6cc9acf87bb9cb50add3593d880ba325b4a9f587_ClientProxy.hashCode(Unknown Source)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfPresent(ConcurrentHashMap.java:1806)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.evictEntry(BoundedLocalCache.java:912)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.expireAfterWriteEntries(BoundedLocalCache.java:836)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.expireEntries(BoundedLocalCache.java:785)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.maintenance(BoundedLocalCache.java:1491)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.performCleanUp(BoundedLocalCache.java:1460)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache$PerformCleanupTask.run(BoundedLocalCache.java:3359)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache$PerformCleanupTask.exec(BoundedLocalCache.java:3346)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

Expected behavior

Application should run with no exceptions

Actual behavior

No response

How to Reproduce?

No response

Output of uname -a or ver

Darwin XXXXX.local 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64 x86_64

Output of java -version

openjdk version “18.0.1” 2022-04-19

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.13.2.Final

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

No response

Additional information

As a workaround, the accessToken can be used as method parameter.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 26 (25 by maintainers)

Most upvoted comments

In that case, maybe just a simple warning in the dedicated guide ?

So essentially a cached method parameter is a request scoped bean, we get this issue?

If so, then I think it’s something we can detect at build time and warn or even fail. @Ladicek @mkouba @gwenneg WDYT?

Yeah agree, failing a build in such case seems like a good idea to me.

Yes that’s the workaround. The issue isn’t linked with token propagation, i will rename the issue. It could be worth noting this limit somewhere.

In debugging session, the key is indeed org.eclipse.microprofile.jwt.OidcJsonWebTokenProducer_ProducerMethod_currentAccessToken_6cc9acf87bb9cb50add3593d880ba325b4a9f587_ClientProxy

Trying to check how the key gets injected, and to code a reproducer.

Ok with more insights, the issue happens when the cached method parameter is a Principal.

Please find a reproducer. I just used the dev-ui to trigger call to my service.

https://github.com/jtama/cache-oidc-reproducer

Sounds like the token is part of the cache key? Which is probably a bad idea?

EDIT: though looking at the code, I’m not sure how that would happen…