didi/DoKit · error · IllegalStateException
Executor service already set.
Error message
Executor service already set.
What it means
DokitPicasso.Builder.executor() throws IllegalStateException when an ExecutorService has already been set on this builder. Like the other Builder components, the executor is single-assignment to prevent silent replacement of a configured component.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java:741
}
if (this.downloader != null) {
throw new IllegalStateException("Downloader already set.");
}
this.downloader = downloader;
return this;
}
/**
* Specify the executor service for loading images in the background.
* <p>
* Note: Calling {@link DokitPicasso#shutdown() shutdown()} will not shutdown supplied executors.
*/
public Builder executor(ExecutorService executorService) {
if (executorService == null) {
throw new IllegalArgumentException("Executor service must not be null.");
}
if (this.service != null) {
throw new IllegalStateException("Executor service already set.");
}
this.service = executorService;
return this;
}
/** Specify the memory cache used for the most recent images. */
public Builder memoryCache(Cache memoryCache) {
if (memoryCache == null) {
throw new IllegalArgumentException("Memory cache must not be null.");
}
if (this.cache != null) {
throw new IllegalStateException("Memory cache already set.");
}
this.cache = memoryCache;
return this;
}
/** Specify a listener for interesting events. */View on GitHub (pinned to 626827cddb)
Solutions
- Ensure executor() is called at most once per Builder
- Consolidate executor selection into one place (single init method)
- Use a new Builder if the whole configuration must be redone
Example fix
// before builder.executor(defaultExecutor); builder.executor(customExecutor); // IllegalStateException // after builder.executor(customExecutor);
Defensive patterns
Strategy: validation
Validate before calling
// Configure executor in exactly one place builder.executor(Executors.newFixedThreadPool(4)); // single call site
Try / catch
try { builder.executor(s); } catch (IllegalStateException e) { if (!e.getMessage().contains("Executor service already set")) throw e; } Prevention
- Centralize builder configuration; audit for duplicate executor() calls when merging init code
When it happens
Trigger: Calling builder.executor(...) twice on the same Builder instance, e.g. a default executor set in a base init method and a custom one set later by an app-specific init.
Common situations: Library initialization code that sets an executor, plus app-level code that sets another; refactors that added a second executor() call without removing the first.
Related errors
- Downloader already set.
- Memory cache already set.
- Listener already set.
- Transformer already set.
- RequestHandler already registered.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/b2187c445d29c459.
Report an issue: GitHub.