lingochamp/FileDownloader · error · IllegalArgumentException

listener must not be null!

Error message

listener must not be null!

What it means

DownloadEventPoolImpl.addListener() rejects null listener objects with an explicit IllegalArgumentException('listener must not be null!'). The event pool stores listeners per event id and cannot register a null callback.

Solutions

  1. Pass a non-null IDownloadListener implementation to addListener
  2. Null-check or early-return if your listener provider can be null: if (listener != null) pool.addListener(eventId, listener)
  3. Fix the DI/wiring so the listener instance is created before registration
  4. Log the call site (or assert) to find which code path passes null

Example fix

// before
pool.addListener("download.complete", myListener); // myListener is null
// after
if (myListener == null) {
    myListener = new DefaultDownloadListener();
}
pool.addListener("download.complete", myListener);
Defensive patterns

Strategy: type-guard

Validate before calling

// before registering
if (eventId == null || listener == null) {
    throw new IllegalArgumentException("eventId and listener must be initialized before addListener");
}

Type guard

boolean canRegister(String eventId, IDownloadListener listener) {
    return eventId != null && listener != null;
}

Try / catch

try {
    pool.addListener(eventId, listener);
} catch (IllegalArgumentException e) {
    log.error("addListener called with null listener; skipping registration", e);
}

Prevention

When it happens

Trigger: Calling downloadEventPool.addListener(eventId, null), or passing a listener variable/field that was never initialized (or set to null by a config/cleanup path).

Common situations: DI/config wiring where a listener bean failed to initialize; passing a listener obtained from a getter that returns null; clearing code that sets the listener field to null but the registration still runs; refactors that renamed a listener without updating the registration site.

Related errors


AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08). Data as JSON: /api/errors/63015da4d353d741. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/event/DownloadEventPoolImpl.java:40

import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.Executor;

/**
 * Implementing actions for event pool.
 */
public class DownloadEventPoolImpl implements IDownloadEventPool {

    private final Executor threadPool = FileDownloadExecutors.newDefaultThreadPool(10, "EventPool");

    private final HashMap<String, LinkedList<IDownloadListener>> listenersMap = new HashMap<>();

    @Override
    public boolean addListener(final String eventId, final IDownloadListener listener) {
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.v(this, "setListener %s", eventId);
        }
        if (listener == null) throw new IllegalArgumentException("listener must not be null!");

        LinkedList<IDownloadListener> container = listenersMap.get(eventId);

        if (container == null) {
            synchronized (eventId.intern()) {
                container = listenersMap.get(eventId);
                if (container == null) {
                    listenersMap.put(eventId, container = new LinkedList<>());
                }
            }
        }


        synchronized (eventId.intern()) {
            return container.add(listener);
        }
    }

View on GitHub (pinned to 6237a8cac1)