greenrobot/EventBus · error · EventBusException

Could not inspect methods of ${clazz.getName()}. Please make

Error message

Could not inspect methods of ${clazz.getName()}. Please make this class visible to EventBus annotation processor to avoid reflection.

What it means

Thrown by SubscriberMethodFinder.findUsingReflectionInPackage/FindState when both Class.getDeclaredMethods() and the fallback Class.getMethods() fail with a LinkageError (superclass of NoClassDefFoundError — see greenrobot/EventBus#149). Reflection needs to load a method's parameter/return types to enumerate methods; if any referenced type is missing from the classpath at that moment, the JVM throws NoClassDefFoundError and EventBus wraps it, telling you to make the class visible to the annotation processor so reflection (and thus the fragile linkage) is avoided entirely.

Source

Thrown at EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java:166

    }

    private void findUsingReflectionInSingleClass(FindState findState) {
        Method[] methods;
        try {
            // This is faster than getMethods, especially when subscribers are fat classes like Activities
            methods = findState.clazz.getDeclaredMethods();
        } catch (Throwable th) {
            // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
            try {
                methods = findState.clazz.getMethods();
            } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
                String msg = "Could not inspect methods of " + findState.clazz.getName();
                if (ignoreGeneratedIndex) {
                    msg += ". Please consider using EventBus annotation processor to avoid reflection.";
                } else {
                    msg += ". Please make this class visible to EventBus annotation processor to avoid reflection.";
                }
                throw new EventBusException(msg, error);
            }
            findState.skipSuperClasses = true;
        }
        for (Method method : methods) {
            int modifiers = method.getModifiers();
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length == 1) {
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                    if (subscribeAnnotation != null) {
                        Class<?> eventType = parameterTypes[0];
                        if (findState.checkAdd(method, eventType)) {
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                        }
                    }
                } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {

View on GitHub (pinned to 0194926b3b)

Solutions

  1. Add the missing class (named in the LinkageError/NoClassDefFoundError cause) to the runtime/test classpath
  2. Enable the EventBus annotation processor + subscriber index so methods are resolved at compile time: annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.3.1' and EventBus.builder().addIndex(new MySubscriberInfoIndex(...))
  3. In JVM tests, use Robolectric or add the missing android stubs so method resolution succeeds
  4. Avoid subscriber method signatures referencing optional/variant-specific types; wrap them in types that are always present

Example fix

// before: JVM unit test fails with EventBusException wrapping NoClassDefFoundError: android/net/Uri
public class HeadlinesSubscriber {
    @Subscribe public void onUri(android.netUri uri) { ... }
}

// after: test-only stub or Robolectric
testImplementation 'org.robolectric:robolectric:4.11'
// or remove the Android type from the subscriber signature
@Subscribe public void onUriEvent(UriEvent event) { ... }
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-flight: can we reflect over the class without linkage errors?
try {
    clazz.getDeclaredMethods();
} catch (LinkageError error) {
    throw new IllegalStateException(
        "Class " + clazz.getName() + " references missing types; fix classpath or use subscriber index", error);
}

Try / catch

try {
    EventBus.getDefault().register(subscriber);
} catch (EventBusException e) {
    if (e.getCause() instanceof LinkageError) {
        // missing dependency at runtime: report which class failed to link
        Log.e(TAG, "Linkage problem scanning " + subscriber.getClass().getName(), e);
        return; // skip registration instead of crashing the app
    }
    throw e;
}

Prevention

When it happens

Trigger: A subscriber (or its superclass) has a method signature referencing a class not on the runtime classpath — e.g. methods referencing optional SDK classes, stubbed android.jar in unit tests, or classes provided by a different flavor/build variant; NoClassDefFoundError raised lazily while getDeclaredMethods() resolves parameter types.

Common situations: JVM unit tests of Android code where subscriber signatures mention Android classes not stubbed by the test runner; optional-dependency patterns; fat-jar packaging that excludes transitive classes referenced in method descriptors; proguard-assisted removal of classes still referenced in kept method signatures.

Related errors


AI-assisted analysis of greenrobot/EventBus@0194926b3b (2026-08-14). Data as JSON: /api/errors/94c797e3ef79c4d8. Report an issue: GitHub.