mercredi 15 mars 2023

NullPointerException inside a method called via the reflection API

I'm getting a NullPointerException when I try to access a static property via reflection.

This is a simplified version of my class:

package test;

@Component
public class CallMe {
  private static Foo foo;

  // Autowired constructor to "inject" the static field
  @Autowired
  public CallMe(Foo autowiredFoo) {
    CallMe.foo = autowiredFoo;
  }

  public static Thing doSomething() {
    return CallMe.foo.bar();
  }
}

And this is the code calling the method:

Class<?> clazz = Class.forName("test.CallMe");
Method method = clazz.getMethod("doSomething", (Class<?>[]) new Class[0]);
Thing theThing = (Thing) method.invoke(null, new Object[0]);

The NullPointerException happens because CallMe.foo is null when I call doSomething via the reflection API. However, my log reads something like this:

Constructor begins
- autowiredFoo is NOT null
- foo is NOT null
Constructor ends
doSomething begins
- foo is null !!!
- NullPointerException

It's not a race condition, I can delay the call to the static method as long as I want.

Why does this happen? Is the reflection API creating a different "copy" of the class, instead of using the one already loaded? Or am I missing something?

And more importantly, how can I solve it? The obvious answer would be "don't declare your method as static if it really isn't static, duh...", but sadly that's not an option. The calling method is in a third-party library and they made it a requeriment that doSomething must be static.





Aucun commentaire:

Enregistrer un commentaire