{"record":{"id":"c1fb3f5a2f909ffe","repo":"brettwooldridge/HikariCP","slug":"wrapped-datasource-is-not-an-instance-of-iface","errorCode":null,"errorMessage":"Wrapped DataSource is not an instance of ${iface}","messagePattern":"Wrapped DataSource is not an instance of (.+?)","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/zaxxer/hikari/HikariDataSource.java","lineNumber":201,"sourceCode":"   public <T> T unwrap(Class<T> iface) throws SQLException\n   {\n      if (iface.isInstance(this)) {\n         return (T) this;\n      }\n\n      var p = pool;\n      if (p != null) {\n         final var unwrappedDataSource = p.getUnwrappedDataSource();\n         if (iface.isInstance(unwrappedDataSource)) {\n            return (T) unwrappedDataSource;\n         }\n\n         if (unwrappedDataSource != null) {\n            return unwrappedDataSource.unwrap(iface);\n         }\n      }\n\n      throw new SQLException(\"Wrapped DataSource is not an instance of \" + iface);\n   }\n\n   /** {@inheritDoc} */\n   @Override\n   public boolean isWrapperFor(Class<?> iface) throws SQLException\n   {\n      if (iface.isInstance(this)) {\n         return true;\n      }\n\n      var p = pool;\n      if (p != null) {\n         final var unwrappedDataSource = p.getUnwrappedDataSource();\n         if (iface.isInstance(unwrappedDataSource)) {\n            return true;\n         }\n\n         if (unwrappedDataSource != null) {","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/brettwooldridge/HikariCP/blob/a4d93f4f85517f90e632b795486d7102e933d7ff/src/main/java/com/zaxxer/hikari/HikariDataSource.java#L183-L219","documentation":"HikariDataSource.unwrap(iface) only succeeds when the underlying (unwrapped) DataSource is an instance of the requested interface, or the delegate itself can unwrap it. HikariCP wraps a user-supplied DataSource, so it can only forward unwrap calls to what it actually wraps; otherwise it throws SQLException.","triggerScenarios":"Calling ds.unwrap(OracleDataSource.class) (or any driver-specific class) when the pool was built from a DriverDataSource (jdbcUrl-based) which has no such type; unwrapping to a class the real driver DataSource does not implement; calling unwrap before the pool exists (pool == null).","commonSituations":"Migrating from native driver DataSources to HikariCP while keeping vendor-specific unwrap calls (e.g. oracle.ucp, MysqlDataSource); unwrap() called on a HikariDataSource created with jdbcUrl instead of dataSource instance.","solutions":["Call isWrapperFor(iface) before unwrap() and skip the vendor-specific path when it returns false","Use standard JDBC interfaces (java.sql.Connection, javax.sql.DataSource) instead of vendor classes where possible","Construct the pool with config.setDataSource(realVendorDataSource) so the vendor type is actually underneath and unwrap succeeds","Pass the vendor-specific handle out-of-band (keep your own reference) instead of unwrapping"],"exampleFix":"// before\nOracleDataSource ods = hikariDs.unwrap(OracleDataSource.class); // throws\n\n// after\nif (hikariDs.isWrapperFor(OracleDataSource.class)) {\n   OracleDataSource ods = hikariDs.unwrap(OracleDataSource.class);\n} else {\n   // fall back to standard JDBC or keep a direct vendor reference\n}","handlingStrategy":"type-guard","validationCode":"if (!hikariDs.isWrapperFor(VendorDataSource.class)) {\n    // use standard JDBC path or a kept vendor reference\n}","typeGuard":"boolean canUnwrapDs(DataSource ds, Class<?> iface) {\n    try { return ds.isWrapperFor(iface); }\n    catch (SQLException e) { return false; }\n}","tryCatchPattern":"try { v = ds.unwrap(iface); }\ncatch (SQLException e) {\n    if (e.getMessage().contains(\"not an instance of\")) { /* fallback to standard API */ }\n    else throw e;\n}","preventionTips":["Always call isWrapperFor before unwrap","Configure pool with the vendor DataSource instance if you need vendor unwrap","Avoid vendor-specific unwrap on jdbcUrl-built pools"],"tags":["hikaricp","jdbc","unwrap","reflection"],"backgroundTag":null,"analyzedSha":"a4d93f4f85517f90e632b795486d7102e933d7ff","analyzedAt":"2026-08-14T12:11:37.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}