-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Lazily perform reflection when Instance<> is used #45276
base: main
Are you sure you want to change the base?
Conversation
a0bf32c
to
9f00d26
Compare
The idea here is to save a few reflection calls that might never end up being used (this is the case with some Quarkus REST providers)
I realized that I want to do similar things to make ClassLoader var1 = Thread.currentThread().getContextClassLoader();
Class var3 = Class.forName("com.fasterxml.jackson.databind.ObjectMapper", false, var1); |
9f00d26
to
a5e3177
Compare
The latest commit changes things up and essentially moves stuff out of the constructor into a purposely generated supplier. However this doesn't completely solve the problem of not loading I could envision expanding the method used here to other places in the Arc code where |
/** | ||
* Meant to be used by generated code in order to easily construct a supplier for lazily created values | ||
*/ | ||
public abstract class AbstractValueSupplier<T> implements Supplier<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Can get
be called multiple times on these suppliers? If so, then I need to guard against it implementing the get
method and having the generated logic in a doGet
or something.
a5e3177
to
5f22568
Compare
I have a few silly questions ;-).
Is there some static init performed by BTW I cannot download the flamegraph from #45276 (comment) - it seems to be a private image. |
This is an excellent question. It should just be
I want to avoid loading the class altogether if possible, until this class is actually used. But if that is not possible (which given that we probably need types, I assume is the case), at the very least I want to avoid all the reflective calls since it's entirely possible that this metadata will never be needed.
I can produce this for you, or give you instructions on how to produce it on your own if you like |
Right, it would not change anything. I was just trying to understand the broader RR context.
Understood, but is one constructor lookup really worth the effort? |
That's what I'm trying to understand. I would like to understand what these generated classes actually do and whether the metadata they pull in their constructor is needed when the bean is created, or if it is needed only to support some small part of the Arc/CDI API. |
So in this particular case the modification that matters is in the We need the java member (field, constructor, etc.) in order to support injection of One thing that we could do (and probably should do ;-) is to only collect the injection point metadata when needed, i.e. find all beans that match the given |
🙏🏽 |
@mkouba would you be so kind to explain to me why for example the generated |
Hm, it's because it injects the BTW this change would not help for |
🙏🏽 |
The idea here is to save a few reflection calls
that might never end up being used (this is the
case with some Quarkus REST providers)
For example
io.quarkus.resteasy.reactive.jackson.runtime.serialisers.FullyFeaturedServerJacksonMessageBodyReader
has the following constructor:
With the existing version of the code the generated
FullyFeaturedServerJacksonMessageBodyReader_Bean
looks (partly) like this:With this change it becomes:
This means that if
FullyFeaturedServerJacksonMessageBodyReader
is never used (which is most of the time), no reflective call will be made to look up its constructorP.S. The change does the minimum possible to achieve what I had in mind,
it definitely is not polished in any way.