{"record":{"id":"e5a658d525192ce8","repo":"Konloch/bytecode-viewer","slug":"factory-already-registered-with-key-key","errorCode":null,"errorMessage":"factory already registered with key: ${key}","messagePattern":"factory already registered with key: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/the/bytecode/club/bytecodeviewer/bootloader/loader/AbstractLoaderFactory.java","lineNumber":50,"sourceCode":"\n    private static final String DEFAULT_KEY = \"default-factory\";\n    private static final Map<String, LoaderFactory<?>> FACTORY_CACHE = new HashMap<>();\n\n    public static void register(LoaderFactory<?> factory)\n    {\n        register(DEFAULT_KEY, factory);\n    }\n\n    public static void register(String key, LoaderFactory<?> factory)\n    {\n        if (key == null || factory == null)\n        {\n            throw new IllegalArgumentException(\"null key or factory\");\n        }\n\n        if (FACTORY_CACHE.containsKey(key))\n        {\n            throw new IllegalArgumentException(\"factory already registered with key: \" + key);\n        }\n\n        FACTORY_CACHE.put(key, factory);\n    }\n\n    public static void unregister(String key)\n    {\n        if (key == null)\n        {\n            throw new IllegalArgumentException(\"null key\");\n        }\n\n        if (!FACTORY_CACHE.containsKey(key))\n        {\n            throw new IllegalArgumentException(\"factory doesn't key for key: \" + key);\n        }\n\n        FACTORY_CACHE.remove(key);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/Konloch/bytecode-viewer/blob/31430e0033fa220db566b5ef461256727ff6793b/src/main/java/the/bytecode/club/bytecodeviewer/bootloader/loader/AbstractLoaderFactory.java#L32-L68","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nregister(\"class\", new ClassLoaderFactory()); // second init throws\n// after\nif (findOrNull(\"class\") == null) register(\"class\", new ClassLoaderFactory());","handlingStrategy":"validation","validationCode":"boolean alreadyRegistered;\ntry { AbstractLoaderFactory.find(key); alreadyRegistered = true; } catch (IllegalArgumentException e) { alreadyRegistered = false; }\nif (!alreadyRegistered) AbstractLoaderFactory.register(key, factory);","typeGuard":null,"tryCatchPattern":"try { AbstractLoaderFactory.register(key, factory); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"factory already registered\")) {\n        log.debug(\"loader {} already registered, skipping\", key); // treat as idempotent\n    } else throw e;\n}","preventionTips":["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"],"tags":["java","loader","registry","duplicate-key"],"backgroundTag":"duplicate-registration","analyzedSha":"31430e0033fa220db566b5ef461256727ff6793b","analyzedAt":"2026-09-05T18:22:22.725Z","contentChangedAt":"2026-09-05T18:22:22.725Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}