{"record":{"id":"0430904972258932","repo":"alibaba/druid","slug":"datasource-inited","errorCode":null,"errorMessage":"dataSource inited.","messagePattern":"dataSource inited\\.","errorType":"validation","errorClass":"DruidRuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java","lineNumber":2236,"sourceCode":"\n    public boolean isAsyncCloseConnectionEnable() {\n        if (isRemoveAbandoned()) {\n            return true;\n        }\n        return asyncCloseConnectionEnable;\n    }\n\n    public void setAsyncCloseConnectionEnable(boolean asyncCloseConnectionEnable) {\n        this.asyncCloseConnectionEnable = asyncCloseConnectionEnable;\n    }\n\n    public ScheduledExecutorService getCreateScheduler() {\n        return createScheduler;\n    }\n\n    public void setCreateScheduler(ScheduledExecutorService createScheduler) {\n        if (isInited()) {\n            throw new DruidRuntimeException(\"dataSource inited.\");\n        }\n        this.createScheduler = createScheduler;\n    }\n\n    public ScheduledExecutorService getDestroyScheduler() {\n        return destroyScheduler;\n    }\n\n    public void setDestroyScheduler(ScheduledExecutorService destroyScheduler) {\n        if (isInited()) {\n            throw new DruidRuntimeException(\"dataSource inited.\");\n        }\n        this.destroyScheduler = destroyScheduler;\n    }\n\n    public boolean isInited() {\n        return this.inited;\n    }","sourceCodeStart":2218,"sourceCodeEnd":2254,"githubUrl":"https://github.com/alibaba/druid/blob/fa8dc9912637a2f729eef9f55356621fec18d40e/core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java#L2218-L2254","documentation":"DruidRuntimeException thrown by setCreateScheduler when the datasource has already been initialized (isInited() returns true). Scheduler executors are wired into the pool's lifecycle at init time; swapping one afterward would leave the running pool referencing the old executor, so Druid forbids it.","triggerScenarios":"Calling dataSource.setCreateScheduler(...) after dataSource.init() has run, or after the first getConnection() triggered lazy init. The isInited() guard at line 2232 throws.","commonSituations":"Spring/guice bean wiring that injects a scheduler via a setter after the datasource bean is constructed and initialized; calling init() explicitly then reconfiguring; reusing a datasource instance and trying to swap schedulers.","solutions":["Set createScheduler BEFORE init() / first getConnection() (in bean setup, before the pool starts).","If the pool is already running, close() it, create a new DruidDataSource, set the scheduler, then init().","Move scheduler bean injection to constructor/early init so it is applied during datasource construction."],"exampleFix":"// before\ndataSource.init();\ndataSource.setCreateScheduler(myScheduler); // throws\n// after\ndataSource.setCreateScheduler(myScheduler);\ndataSource.init();","handlingStrategy":"validation","validationCode":"if (dataSource.isInited()) {\n    throw new IllegalStateException(\"set createScheduler before init(); pool is already initialized\");\n}\ndataSource.setCreateScheduler(scheduler);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure all executors/schedulers during bean construction, before any getConnection().","Treat the datasource as immutable after init().","Trigger lazy init deliberately late so config setters all run first."],"tags":["config","lifecycle","scheduler","init-order"],"backgroundTag":null,"analyzedSha":"fa8dc9912637a2f729eef9f55356621fec18d40e","analyzedAt":"2026-08-14T04:55:06.789Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}