-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Quarks Cache is not working in Bean that is created via a Producer #34436
Comments
/cc @gwenneg (cache) |
We'd need a sample application the reproduces this behavior in order to investigate |
This ^ and especially we need to see the |
This is my producer for my local test environment. |
TestApplication |
I could not reproduce the problem with the sample application added above |
Okay, I was able to reproduce it after all. @gwenneg can you have a look at this one? It does seem important to fix this one |
I don't see any |
@mkouba When:
Is the corresponding interceptor supposed to work? |
No, it isn't. Interceptors and decorators are not applied to the return value of a producer method or the value of a producer field. (see Binding an interceptor to a bean). And the reason is that the container does not control instantiation of the bean in that case. In CDI 2.0 the |
https://quarkus.io/version/2.13/guides/cdi-reference#simplified-producer-method-declaration |
So, @mkouba Is this mentioned in the CDI doc? I don't see it in https://quarkus.io/guides/cdi-reference#limitations but maybe it's somewhere else. |
Not Quarkus, but any CDI implementation really.
It's not a limitation of ArC. It's a "feature" of the CDI spec. The truth is that CDI Full has the |
This default behavior of the spec seems very weird to me... Could we perhaps have some kind of Quarkus specific opt-in that would be utilized by cache (and whatever else we decide)? |
It's not so weird when you think about the general purpose of producer methods - give the user the control of the instantiation of a bean, i.e. it's not the container that constructs the bean instance. Also it's a bit challenging from technical point of view. |
From the implementors perspective, perhaps. But it's very surprising from a user's perspective (as is evident from this thread) |
It is not "challenging", it is impossible. We have no idea what is the class of the object the producer method returns, so we can't create the subclass. I mean, it is impossible in general, because the producer method may call other methods that create the ultimate object the producer returns. There are special cases we could support at the cost of the following heroics: perform control flow analysis on the bytecode of the method to determine if all code paths through the producer method end up instantiating and returning a known class, generate subclasses for those known classes, rewrite the bytecode of that producer so that those code paths return the subclasses instead. Pretty sure we don't want to do that. |
In that case, can we at least log a strong worded warning? |
@geoand Yes, but it's not supported for good reasons. BTW the same applies to synthetic beans, because only managed beans (aka beans implemented by Java classes) support interception.
Or generate the subclass at runtime... which is not idiomatic for quarkus, nor an option for native image.
We could. Until someone else complains that those warnings are superfluous for this particular use case (it wouldn't be for the first time ;-). |
I don't think we should add a warning for something that works exactly as it should. I mean, it is not just interceptors that don't work for producer beans, What we might be able to do is some build-time friendly variant of @Produces
@RequestScoped
@SupportInterceptionOf(MyClass.class) // name subject to bike shedding of course
public MyClass produceMyClass(InterceptionFactory factory) {
return factory.createInterceptedInstance(new MyClass());
} That would mean:
Alternatively, we could ditch CDI's @Produces
@RequestScoped
@SupportInterceptionOf(MyClass.class) // name subject to bike shedding of course
public MyClass produceMyClass(ArcInterceptedBeanFactory factory) { // name intentionally ugly
// could also accept arguments to pass to the constructor, probably?
return factory.createInterceptedInstance(MyClass.class);
} |
(Looking at the |
Ah, I didn't know we have an issue for that. Will copy my comments there. |
I’m not sure I would add a warning in the logs but we need a warning in the documentation. And I think we should also point to this warning in the cache doc. |
Don't think it's detectable that easily. Technically, your class |
BTW, if you can do this, you should. |
Describe the bug
I annotated a function with @CacheResult in a class that gets created as a bean by a producer.
The cache is created as I can see in the DEV UI, but no values are written to the cache.
If I create the bean by just adding the @ApplicationScoped annotation and remove the producer everything works fine.
Expected behavior
No response
Actual behavior
No response
How to Reproduce?
No response
Output of
uname -a
orver
No response
Output of
java -version
openjdk version "18.0.2" 2022-07-19
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.16.5.Final
Build tool (ie. output of
mvnw --version
orgradlew --version
)Gradle 7.4
Additional information
No response
The text was updated successfully, but these errors were encountered: