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)
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…