{"record":{"id":"6a23719bc9bc2347","repo":"alibaba/druid","slug":"getstatdata-error","errorCode":null,"errorMessage":"getStatData error","messagePattern":"getStatData error","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"warning","filePath":"core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java","lineNumber":3599,"sourceCode":"            map.put(\"PreparedStatementCacheAccessCount\", this.getCachedPreparedStatementAccessCount());\n            map.put(\"PreparedStatementCacheMissCount\", this.getCachedPreparedStatementMissCount());\n            map.put(\"PreparedStatementCacheHitCount\", this.getCachedPreparedStatementHitCount());\n            map.put(\"PreparedStatementCacheCurrentCount\", this.getCachedPreparedStatementCount());\n            map.put(\"Version\", this.getVersion());\n\n            // 40 -\n            map.put(\"LastErrorTime\", this.getLastErrorTime());\n            map.put(\"LastCreateErrorTime\", this.getLastCreateErrorTime());\n            map.put(\"CreateErrorCount\", this.getCreateErrorCount());\n            map.put(\"DiscardCount\", this.getDiscardCount());\n            map.put(\"ExecuteQueryCount\", this.getExecuteQueryCount());\n\n            map.put(\"ExecuteUpdateCount\", this.getExecuteUpdateCount());\n            map.put(\"InitStackTrace\", this.getInitStackTrace());\n\n            return map;\n        } catch (JMException ex) {\n            throw new IllegalStateException(\"getStatData error\", ex);\n        }\n    }\n\n    public Map<String, Object> getStatData() {\n        final int activeCount;\n        final int activePeak;\n        final Date activePeakTime;\n\n        final int poolingCount;\n        final int poolingPeak;\n        final Date poolingPeakTime;\n\n        final long connectCount;\n        final long closeCount;\n\n        lock.lock();\n        try {\n            poolingCount = this.poolingCount;","sourceCodeStart":3581,"sourceCodeEnd":3617,"githubUrl":"https://github.com/alibaba/druid/blob/fa8dc9912637a2f729eef9f55356621fec18d40e/core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java#L3581-L3617","documentation":"Thrown by getStatDataAndIdentities() (the JMX-backed stat accessor) when reading JMX attribute values raises a JMException. Druid collects ~45 monitoring attributes from its JMX beans; if any bean/attribute access fails it wraps the failure as IllegalStateException(\"getStatData error\", ex) so callers get a single typed exception rather than JMException leaking.","triggerScenarios":"Calling dataSource.getStatDataAndIdentities() while an internal JMX MBean is in an inconsistent state, or an attribute getter throws (e.g. JdbcUtils/JMXUtils serialising a null LastError via getErrorCompositeData). The catch at line 3598 wraps the JMException.","commonSituations":"Concurrent close() racing with stat collection; a custom exceptionSorter/filter corrupting lastError; JMX security manager denying attribute access; an attribute returning a type JMXUtils cannot serialise; monitoring agent (Prometheus exporter, Druid stat JSON) scraping during shutdown.","solutions":["Read the chained JMException (getCause()) to find which attribute access failed and fix that underlying getter/null.","Avoid scraping stats while the DataSource is being closed/init; guard monitoring calls with a started && !closed check.","If using a monitoring integration, ensure it tolerates IllegalStateException and backs off rather than spamming.","Upgrade Druid if this recurs — several attribute-serialisation NPEs were fixed across versions."],"exampleFix":"// before — bare stat read blows up at shutdown\nMap<String,Object> m = dataSource.getStatDataAndIdentities();\n\n// after — guard against pool lifecycle races\nif (!dataSource.isInited() || dataSource.isClosed()) {\n    return Collections.emptyMap();\n}\ntry {\n    return dataSource.getStatDataAndIdentities();\n} catch (IllegalStateException e) {\n    log.warn(\"stat collection failed: {}\", e.getCause().getMessage());\n    return Collections.emptyMap();\n}","handlingStrategy":"try-catch","validationCode":"// guard stat scraping against lifecycle races\nif (!dataSource.isInited() || ((DruidDataSource) dataSource).isClosed()) {\n    return Collections.emptyMap();\n}\nreturn dataSource.getStatDataAndIdentities();","typeGuard":null,"tryCatchPattern":"try {\n    return dataSource.getStatDataAndIdentities();\n} catch (IllegalStateException e) {\n    // chained JMException names the failing attribute\n    log.warn(\"stat read failed: {}\", e.getCause() == null ? e : e.getCause().getMessage());\n    return Collections.emptyMap();\n}","preventionTips":["Do not scrape stats during init/close; guard with isInited() && !isClosed().","Make monitoring scrapers tolerate IllegalStateException and back off.","Upgrade Druid if attribute-serialisation NPEs recur."],"tags":["jmx","monitoring","stats","lifecycle","diagnostics"],"backgroundTag":null,"analyzedSha":"fa8dc9912637a2f729eef9f55356621fec18d40e","analyzedAt":"2026-08-14T04:55:06.789Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}