{"record":{"id":"8a76401224d2eb5e","repo":"quarkusio/quarkus","slug":"resource-being-loaded-more-than-once","errorCode":null,"errorMessage":"Resource being loaded more than once: ","messagePattern":"Resource being loaded more than once: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassLoaderLimiter.java","lineNumber":50,"sourceCode":"    @Override\n    public void openResourceStream(String resourceName, String classLoaderName) {\n        Objects.requireNonNull(resourceName);\n        Objects.requireNonNull(classLoaderName);\n        if (traceAllResourceLoad) {\n            System.out.println(\"Opening resource: \" + resourceName);\n        }\n        if (onHitPrintStacktrace.contains(resourceName)) {\n            final RuntimeException e = new RuntimeException(\"Tracing load of resource: \" + resourceName);\n            e.printStackTrace();\n        }\n        if (vetoedResources.contains(resourceName)) {\n            throw new IllegalStateException(\n                    \"Attempted to load vetoed resource '\" + resourceName + \"' from classloader \" + classLoaderName);\n        }\n        if (atMostOnceResources.contains(resourceName)) {\n            final String previousLoadEvent = atMostOnceResourcesLoaded.put(resourceName, classLoaderName);\n            if (previousLoadEvent != null) {\n                throw new IllegalStateException(\"Resource being loaded more than once: \" + resourceName + \".\\n\" +\n                        \"Attempted load by \" + classLoaderName + \", recorded previous load by \" + previousLoadEvent);\n            }\n        }\n        if (resourceName.endsWith(\".class\")) {\n            //Skip further tracking on classes as it would create unnecessary noise\n            return;\n        }\n        final String previousLoad = allResourcesLoaded.put(resourceName, classLoaderName);\n        if (previousLoad != null) {\n            //This diagnostic has no flag, as it's generally useful, doesn't throw exceptions, and should\n            //generally not log much at all.\n            System.out.println(\n                    \"Resource loaded multiple times: \" + resourceName + \". Currently being loaded by \" + classLoaderName +\n                            \", previous loaded by \" + previousLoad);\n        }\n    }\n\n    @Override","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassLoaderLimiter.java#L32-L68","documentation":"ClassLoaderLimiter tracks resources registered as atMostOnceResources and throws this IllegalStateException the second time any classloader attempts to load them. It is an assertion mechanism that guarantees a resource is opened at most once across all monitored classloaders.","triggerScenarios":"openResourceStream is called for a resource listed in atMostOnceResources that already has a recorded load event in atMostOnceResourcesLoaded (put returns a non-null previous event).","commonSituations":"Tests verifying single-load invariants for config/bootstrap resources; failures when caching is missing and the same resource is re-read, or when two subsystems independently read the same resource.","solutions":["Introduce caching so the resource is read once and reused (e.g. static/holder caching in the loading code).","Identify the two loading classloaders from the message and unify the loading path in one of them.","If duplicate loads are acceptable now, drop the atMostOnceResource registration from the limiter builder."],"exampleFix":"// before\ntry (InputStream in = cl.getResourceAsStream(\"app.properties\")) { ... } // called repeatedly\n// after\nprivate static final Properties PROPS = loadOnce(\"app.properties\");","handlingStrategy":"validation","validationCode":"// ensure single read: cache resource contents at first access\nprivate static final Map<String, byte[]> CACHE = new ConcurrentHashMap<>();\nbyte[] data = CACHE.computeIfAbsent(name, n -> readOnce(n));","typeGuard":null,"tryCatchPattern":"try { open(path); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"Resource being loaded more than once\")) { log.error(\"Duplicate load: {}\", e.getMessage()); } else { throw e; } }","preventionTips":["Cache resource contents instead of re-reading from the classloader.","Centralize resource access in one utility per classloader hierarchy.","Register at-most-once expectations only for resources you control."],"tags":["classloading","test-tooling","classloader-limiter","duplicate-load"],"backgroundTag":"duplicate-resource-load","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}