apache/dubbo · critical · IllegalStateException

FrameworkModel is destroyed

Error message

FrameworkModel is destroyed

What it means

Thrown by FrameworkModel.checkDestroyed() (a private guard invoked before mutating the model). It signals that the FrameworkModel has already completed its destroy lifecycle, so any attempt to obtain the default application model (defaultApplication()) or register a new application (addApplication()) is refused. The model tree is single-use: once destroyed it cannot be revived, and a fresh FrameworkModel must be created instead.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java:295

    void tryDestroyProtocols() {
        synchronized (instLock) {
            if (pubApplicationModels.size() == 0) {
                notifyProtocolDestroy();
            }
        }
    }

    void tryDestroy() {
        synchronized (instLock) {
            if (pubApplicationModels.size() == 0) {
                destroy();
            }
        }
    }

    private void checkDestroyed() {
        if (isDestroyed()) {
            throw new IllegalStateException("FrameworkModel is destroyed");
        }
    }

    private void resetDefaultAppModel() {
        synchronized (instLock) {
            if (this.defaultAppModel != null && !this.defaultAppModel.isDestroyed()) {
                return;
            }
            ApplicationModel oldDefaultAppModel = this.defaultAppModel;
            if (pubApplicationModels.size() > 0) {
                this.defaultAppModel = pubApplicationModels.get(0);
            } else {
                this.defaultAppModel = null;
            }
            if (defaultInstance == this && oldDefaultAppModel != this.defaultAppModel) {
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info("Reset global default application from " + safeGetModelDesc(oldDefaultAppModel) + " to "
                            + safeGetModelDesc(this.defaultAppModel));

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Do not reuse a destroyed FrameworkModel; create a new instance via `new FrameworkModel()` or let DubboBootstrap/FrameworkModel.defaultModel() lazily create a fresh one (destroy resets the global default).
  2. In tests, ensure each test creates its own FrameworkModel/ApplicationModel and destroys it fully in teardown, or call FrameworkModel.destroyAll() to clear the global registry before the next test.
  3. If using DubboBootstrap, start a new DubboBootstrap instance rather than calling methods on the one you destroyed.
  4. Guard access with `if (!frameworkModel.isDestroyed())` before calling defaultApplication()/addApplication().

Example fix

// before
FrameworkModel fm = FrameworkModel.defaultModel();
fm.destroy();
ApplicationModel app = fm.defaultApplication(); // throws

// after
FrameworkModel fm = FrameworkModel.defaultModel();
fm.destroy();
// destroyed model resets the global default; a new one is created lazily
ApplicationModel app = FrameworkModel.defaultModel().defaultApplication();
Defensive patterns

Strategy: validation

Validate before calling

if (frameworkModel == null || frameworkModel.isDestroyed()) {
    frameworkModel = FrameworkModel.defaultModel(); // get/create a live model
}
ApplicationModel app = frameworkModel.defaultApplication();

Prevention

When it happens

Trigger: Calling frameworkModel.defaultApplication() or frameworkModel.addApplication(...) after frameworkModel.destroy() has run. Also occurs when ApplicationModel.of(frameworkModel) is constructed against a destroyed framework, or when a background destroy thread races a re-initialization thread in test harnesses that reuse the same FrameworkModel.

Common situations: Unit/integration tests that call FrameworkModel.defaultModel().destroy() (or DubboBootstrap.getInstance().destroy()) in @AfterEach and then start a new DubboBootstrap in the next test without resetting the global default. Long-running apps that intentionally destroy and re-create the framework. Spring context refresh/destroy cycles where the FrameworkModel bean is scoped incorrectly (singleton reused across restarts).

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/5b8d91a9ea27ce62. Report an issue: GitHub.