hs-web/hsweb-framework · error · UnsupportedOperationException

dataSourceService not ready

Error message

dataSourceService not ready

What it means

DataSourceHolder.checkDynamicDataSourceReady() throws UnsupportedOperationException when the static dynamicDataSourceService reference is still null, i.e. the dynamic datasource service bean was never injected into the holder.

Solutions

  1. Ensure the application includes hsweb-datasource-api/auto-configuration and the dynamic datasource service bean is registered
  2. Call the datasource API only from Spring-managed, post-startup code
  3. Check isDynamicDataSourceReady() before calling and fail gracefully
  4. In tests, initialize the holder manually or mock the service

Example fix

// before
DataSourceHolder.switcher().datasource().use("ds1");
// after
if (DataSourceHolder.isDynamicDataSourceReady()) {
    DataSourceHolder.switcher().datasource().use("ds1");
} else {
    throw new IllegalStateException("dynamic datasource service not initialized");
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!DataSourceHolder.isDynamicDataSourceReady()) {
    throw new IllegalStateException("dynamic datasource service not initialized");
}

Type guard

static boolean canSwitch() {
    return DataSourceHolder.isDynamicDataSourceReady();
}

Try / catch

try {
    DataSourceHolder.switcher().datasource().use(id);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().contains("not ready")) {
        log.error("datasource service missing; using plain JDBC");
    } else throw e;
}

Prevention

When it happens

Trigger: Calling DataSourceHolder.switcher().datasource()/existing()/defaultDataSource (which call the check) in a context where the AopDataSourceSwitcherAutoConfiguration/DataSourceService was not initialized, or before Spring finished wiring the bean.

Common situations: Running code outside the Spring context (unit tests, static initializers); using the datasource API in a module without hsweb-datasource on the classpath/scan; calling switcher very early during startup before the service bean is created.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of hs-web/hsweb-framework@b2cfc85a57 (2026-09-13). Data as JSON: /api/errors/526c78bbdd9968b5. Report an issue: GitHub.

Appendix: source

Thrown at hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/DataSourceHolder.java:30

 */
public final class DataSourceHolder {


    /**
     * 动态数据源服务
     */
    static volatile DynamicDataSourceService dynamicDataSourceService;

    static volatile JdbcSwitcher jdbcSwitcher = new DefaultJdbcSwitcher();
    static volatile R2dbcSwitcher r2dbcSwitcher = new DefaultR2dbcSwicher();

    public static boolean isDynamicDataSourceReady() {
        return dynamicDataSourceService != null;
    }

    public static void checkDynamicDataSourceReady() {
        if (dynamicDataSourceService == null) {
            throw new UnsupportedOperationException("dataSourceService not ready");
        }
    }

    /**
     * @return 动态数据源切换器
     */
    public static JdbcSwitcher switcher() {
        return jdbcSwitcher;
    }

    public static R2dbcSwitcher r2dbcSwitcher() {
        return r2dbcSwitcher;
    }

    /**
     * @return 默认数据源
     */
    public static JdbcDataSource defaultDataSource() {

View on GitHub (pinned to b2cfc85a57)