- Notifications
You must be signed in to change notification settings - Fork 1.9k
Fix NPE caused by uninitialized static variables in interfaces in native images #3256
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
base: main
Are you sure you want to change the base?
Fix NPE caused by uninitialized static variables in interfaces in native images #3256
Conversation
…ive images Signed-off-by: jonghoon park <dev@jonghoonpark.com>
a10815b
to 4dd82c3
Compare I don't understand what is going on here,currently in
Why would this field be set to null when creating a native image? |
hi - could you tell us against what version of Spring AI you're reporting this? and against what version of GraalVM? Which OS? ive attempted to reproduce the bug here [1] on macOS using graalvm for java 24 and haven't yet seen the issue... I wonder if having some sort of proxy / AOP logic is causing that reference to be Alternatively: is it possible you don't have the Reactor libraries on the class path? I don't know.. |
the good news is, as I just realized, is that most of the common BaseAdvisors are also |
I reproduced the bug by following the code provided by the issue #3168. Would you be able to test this repository? tested os:
tested jdk:
The error logs are displayed as follows: There are no issues during normal execution, and there are no problems with the logic. [Note] |
that works! you're right, @dev-jonghoonpark - thank you very much I have qualms about the design of BaseAdvisor. I think the getMethod() should return the Scheduler Factory and it should not be stored as a constant. But still, the code does work on the JVM, because on the JVM the class is loaded from bytes into memory and initialized in the same process. GraalVM, otoh, wants to initialize as much as possible at compile time (sort of like evaluating C macros) so that when it comes to start the program, it can just load the memory straight in. no evaluating and crawling and whatever. So it makes most classes build-time init. This means an interface with a constant value would be fine in a graalvm context, but dynamic variables like the SchedulerFactory .. not so much. the ugliest way ive found to fix this is to just check for null again during the
|
hi, @joshlong trick works too, but forcing the scheduler as I have done as a workaround in the original issue does the trick for the moment (at least for me). Encapsulating all those builders in I am also a bit meh by the fact that those factories are stored in the constants, but it works on the jvm so why not. |
thanks. the only thing we're encapsulating is the non constant default value on the interface, which is initialized at build time but has to be null since there's nothing useful at build time. I agree - it's weird that the default is stored in an interface constant :/ |
related issue: #3168
The
DEFAULT_SCHEDULER
variable in theBaseAdvisor
interface was being initialized to null when running a native image.To address this issue, a separate
SchedulerHolder
class was created to handle the variable initialization properly and ensure it is initialized as expected.