{"record":{"id":"23bf73243fa58890","repo":"apache/dubbo","slug":"applicationmodel-is-destroyed","errorCode":null,"errorMessage":"ApplicationModel is destroyed","messagePattern":"ApplicationModel is destroyed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java","lineNumber":283,"sourceCode":"            this.pubModuleModels.remove(moduleModel);\n            if (moduleModel == defaultModule) {\n                defaultModule = findDefaultModule();\n            }\n        }\n    }\n\n    void tryDestroy() {\n        synchronized (instLock) {\n            if (this.moduleModels.isEmpty()\n                    || (this.moduleModels.size() == 1 && this.moduleModels.get(0) == internalModule)) {\n                destroy();\n            }\n        }\n    }\n\n    private void checkDestroyed() {\n        if (isDestroyed()) {\n            throw new IllegalStateException(\"ApplicationModel is destroyed\");\n        }\n    }\n\n    public List<ModuleModel> getModuleModels() {\n        return Collections.unmodifiableList(moduleModels);\n    }\n\n    public List<ModuleModel> getPubModuleModels() {\n        return Collections.unmodifiableList(pubModuleModels);\n    }\n\n    public ModuleModel getDefaultModule() {\n        if (defaultModule == null) {\n            synchronized (instLock) {\n                if (defaultModule == null) {\n                    defaultModule = findDefaultModule();\n                    if (defaultModule == null) {\n                        defaultModule = this.newModule();","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java#L265-L301","documentation":"Thrown by ApplicationModel.checkDestroyed when an operation is attempted on an ApplicationModel that has already been destroyed. After destruction the model is unusable; further access (creating modules, registering configs, etc.) is rejected to prevent use-after-shutdown bugs.","triggerScenarios":"Any guarded operation on ApplicationModel after destroy() has run. Common in test teardown or application shutdown sequences where a background/late task touches the model after it was torn down.","commonSituations":"Unit/integration tests that destroy the ApplicationModel in @AfterEach but a later step still references it. Hot-reload or redeploy that destroys a model while async export/import tasks are still running. Spring context refresh/close ordering where beans outlive the Dubbo model. Static references to a model held past its lifecycle.","solutions":["Ensure no tasks/threads touch the ApplicationModel after destroy(); order shutdown so Dubbo stops first or wait for in-flight work.","In tests, create a fresh ApplicationModel per test rather than reusing a destroyed one.","Release static/long-lived references to the model before destruction."],"exampleFix":"// before\napplicationModel.destroy();\n// ... later, async task still running:\nmoduleModel = applicationModel.getDefaultModule(); // throws\n\n// after\n// await/quiesce async tasks BEFORE destroy, or recreate the model.","handlingStrategy":"type-guard","validationCode":"// Guard all post-shutdown access\nif (applicationModel.isDestroyed()) {\n    throw new IllegalStateException(\n        \"ApplicationModel already destroyed; cannot proceed with this operation\");\n}","typeGuard":"static boolean isUsable(ApplicationModel m) {\n    return m != null && !m.isDestroyed();\n}","tryCatchPattern":"try {\n    applicationModel.getDefaultModule();\n} catch (IllegalStateException e) {\n    if (\"ApplicationModel is destroyed\".equals(e.getMessage())) {\n        // recreate or obtain a fresh model rather than reuse the destroyed one\n        applicationModel = ApplicationModel.defaultModel();\n    } else {\n        throw e;\n    }\n}","preventionTips":["Order shutdown so Dubbo teardown happens after all application work completes.","In tests, create and destroy an ApplicationModel per test; never reuse destroyed models.","Clear static/long-lived references to a model before destroying it.","Quiesce async tasks before calling destroy()."],"tags":["lifecycle","scope-model","shutdown"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}