Konloch/bytecode-viewer · error · IllegalArgumentException
factory already registered with key: ${key}
Error message
factory already registered with key: ${key} What it means
Thrown by AbstractLoaderFactory.register when a factory has already been registered under the same key in FACTORY_CACHE. The registry enforces one factory per key so lookups are unambiguous; duplicate registration is treated as a programming/config error rather than an overwrite.
Source
Thrown at src/main/java/the/bytecode/club/bytecodeviewer/bootloader/loader/AbstractLoaderFactory.java:50
private static final String DEFAULT_KEY = "default-factory";
private static final Map<String, LoaderFactory<?>> FACTORY_CACHE = new HashMap<>();
public static void register(LoaderFactory<?> factory)
{
register(DEFAULT_KEY, factory);
}
public static void register(String key, LoaderFactory<?> factory)
{
if (key == null || factory == null)
{
throw new IllegalArgumentException("null key or factory");
}
if (FACTORY_CACHE.containsKey(key))
{
throw new IllegalArgumentException("factory already registered with key: " + key);
}
FACTORY_CACHE.put(key, factory);
}
public static void unregister(String key)
{
if (key == null)
{
throw new IllegalArgumentException("null key");
}
if (!FACTORY_CACHE.containsKey(key))
{
throw new IllegalArgumentException("factory doesn't key for key: " + key);
}
FACTORY_CACHE.remove(key);View on GitHub (pinned to 31430e0033)
Solutions
- Guard with FACTORY_CACHE check or a boolean initialized flag so registration runs once.
- Call AbstractLoaderFactory.unregister(key) before re-registering the same key.
- Use distinct, namespaced keys (e.g. plugin-id:loader-name) for each provider.
- In tests, unregister in teardown to reset the static registry.
Example fix
// before
register("class", new ClassLoaderFactory()); // second init throws
// after
if (findOrNull("class") == null) register("class", new ClassLoaderFactory()); Defensive patterns
Strategy: validation
Validate before calling
boolean alreadyRegistered;
try { AbstractLoaderFactory.find(key); alreadyRegistered = true; } catch (IllegalArgumentException e) { alreadyRegistered = false; }
if (!alreadyRegistered) AbstractLoaderFactory.register(key, factory); Try / catch
try { AbstractLoaderFactory.register(key, factory); }
catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("factory already registered")) {
log.debug("loader {} already registered, skipping", key); // treat as idempotent
} else throw e;
} Prevention
- Make registration idempotent — guard with a flag or unregister-then-register
- Use unique namespaced keys per plugin/module
- In tests, clean up registrations in teardown since the cache is static
- Never re-run init routines without checking prior state
When it happens
Trigger: Calling register("myloader", factory) twice with the same key, e.g. re-running an init routine, two plugin modules registering the same loader name, or a hot-reload path that re-invokes registration without unregistering first.
Common situations: Plugin systems where multiple jars contribute the same loader key; application restart within the same JVM (static cache persists); unit tests registering fixtures without cleanup in @Before/@After.
Related errors
- null key or factory
- null key
- factory doesn't key for key: ${key}
- '${codebase}' is not a directory
- Unknown constant pool tag ${tag}
AI-assisted analysis of Konloch/bytecode-viewer@31430e0033 (2026-09-05).
Data as JSON: /api/errors/e5a658d525192ce8.
Report an issue: GitHub.