didi/DoKit · error · ReflectedException
Need a caller!
Error message
Need a caller!
What it means
Reflector.check throws 'Need a caller!' when the resolved member is an INSTANCE member but caller is null. Reflection cannot invoke a non-static Field.get/Method.invoke on a null receiver, so the guard fails fast with an explicit message instead of the JVM's ambiguous NullPointerException.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/util/Reflector.java:104
throw new ReflectedException("Oops!", e.getTargetException());
} catch (Throwable e) {
throw new ReflectedException("Oops!", e);
}
}
protected Object checked(@Nullable Object caller) throws ReflectedException {
if (caller == null || mType.isInstance(caller)) {
return caller;
}
throw new ReflectedException("Caller [" + caller + "] is not a instance of type [" + mType + "]!");
}
protected void check(@Nullable Object caller, @Nullable Member member, @NonNull String name) throws ReflectedException {
if (member == null) {
throw new ReflectedException(name + " was null!");
}
if (caller == null && !Modifier.isStatic(member.getModifiers())) {
throw new ReflectedException("Need a caller!");
}
checked(caller);
}
public Reflector bind(@Nullable Object caller) throws ReflectedException {
mCaller = checked(caller);
return this;
}
public Reflector unbind() {
mCaller = null;
return this;
}
public Reflector field(@NonNull String name) throws ReflectedException {
try {
mField = findField(name);
mField.setAccessible(true);View on GitHub (pinned to 626827cddb)
Solutions
- Pass a real instance: use Reflector.with(instance) or callByCaller(realInstance, args)
- If the member should be static, verify with Modifier.isStatic(member.getModifiers()) — maybe the wrong overload/signature resolved to an instance member
- Null-check the caller object before invoking when it comes from another reflective call
Example fix
// before
Reflector.on(Activity.class).method("getApplication").call(); // instance method, no caller
// after
Application app = Reflector.with(activity).method("getApplication").call(); Defensive patterns
Strategy: validation
Validate before calling
if (caller == null && !Modifier.isStatic(member.getModifiers())) {
// bind an instance first
Reflector.with(instance);
} Type guard
static boolean canCallWithoutCaller(java.lang.reflect.Member m) {
return Modifier.isStatic(m.getModifiers());
} Prevention
- Use Reflector.with(instance) for instance members, Reflector.on(class) only for static ones
- Null-check objects returned from earlier reflective calls before using them as callers
When it happens
Trigger: Calling callByCaller(null, args) or get(null) on an instance method/field; using Reflector.on(SomeClass.class).method("instanceMethod").call() without binding an instance via bind()/with(); the mCaller was unbound() before the call.
Common situations: Static-looking helper methods that are actually instance methods in that OS version; forgetting .with(instance) after on(class); a null object obtained from a prior failed reflective get being passed as caller.
Related errors
- Constructor was null!
- Caller [" + caller + "] is not a instance of type [" + mType
- name + " was null!"
- Unsupported object type: " + object.getClass().getName()
- No similar method ${name} with params ${types} could be foun
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/41715f904691b005.
Report an issue: GitHub.