{"record":{"id":"a9cd9d755f7f0ce7","repo":"t8y2/dbx","slug":"not-a-wrapper-for-iface-name","errorCode":null,"errorMessage":"Not a wrapper for <iface name>","messagePattern":"Not a wrapper for <iface name>","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"agents/common/src/main/java/com/dbx/agent/JdbcConnectionPoolRegistry.java","lineNumber":1133,"sourceCode":"\n        @Override\n        public int getLoginTimeout() {\n            // Hikari waits this long for in-flight add tasks before closing its connection bag.\n            long timeoutSeconds = (connectionTimeoutMillis + 999L) / 1_000L;\n            return (int) Math.min(Integer.MAX_VALUE, Math.max(1L, timeoutSeconds));\n        }\n\n        @Override\n        public Logger getParentLogger() throws SQLFeatureNotSupportedException {\n            return Logger.getLogger(\"com.dbx.agent.jdbc.pool\");\n        }\n\n        @Override\n        public <T> T unwrap(Class<T> iface) throws SQLException {\n            if (iface.isInstance(this)) {\n                return iface.cast(this);\n            }\n            throw new SQLException(\"Not a wrapper for \" + iface.getName());\n        }\n\n        @Override\n        public boolean isWrapperFor(Class<?> iface) {\n            return iface.isInstance(this);\n        }\n    }\n\n    private static final class JdbcCheckoutExecutor implements AutoCloseable {\n        private final ExecutorService executor;\n        private final ConnectionReleaseExecutor releaseExecutor;\n\n        private JdbcCheckoutExecutor(int maximumConcurrentCheckouts, ConnectionReleaseExecutor releaseExecutor) {\n            this.executor = boundedExecutor(maximumConcurrentCheckouts, \"dbx-jdbc-checkout\");\n            this.releaseExecutor = releaseExecutor;\n        }\n\n        private Connection checkout(","sourceCodeStart":1115,"sourceCodeEnd":1151,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/common/src/main/java/com/dbx/agent/JdbcConnectionPoolRegistry.java#L1115-L1151","documentation":"Standard JDBC Wrapper.unwrap() behavior: the thrown SQLException indicates the requested interface is not implemented by this pool wrapper. The wrapper only supports unwrapping to interfaces it actually implements (iface.isInstance(this)); the delegate pattern is not exposed here.","triggerScenarios":"Calling connection.unwrap(SomeVendorConnection.class) or dataSource.unwrap(...) where SomeVendorConnection is a driver-specific interface (e.g. OracleConnection, PGConnection) that this wrapper class does not implement.","commonSituations":"Passing pooled connections to driver-specific code that expects to unwrap to the native driver connection (e.g. for Array/Struct support, vendor-specific tuning); libraries like Hibernate or jOOQ trying to unwrap native connections.","solutions":["Avoid vendor-specific APIs on pooled connections, or configure the pool/tooling to use pure JDBC APIs","If native access is required, obtain the physical connection through a supported hook rather than unwrap()","Use isWrapperFor(iface) first to check support before calling unwrap()","Wrap in try-catch and fall back to generic JDBC code paths"],"exampleFix":"// before\nOracleConnection ora = conn.unwrap(OracleConnection.class);\n// after\nif (conn.isWrapperFor(OracleConnection.class)) {\n    OracleConnection ora = conn.unwrap(OracleConnection.class);\n} else {\n    // use generic java.sql APIs\n}","handlingStrategy":"type-guard","validationCode":"if (!connection.isWrapperFor(OracleConnection.class)) {\n    throw new UnsupportedOperationException(\"vendor API unavailable on pooled connection\");\n}","typeGuard":"static <T> Optional<T> tryUnwrap(Wrapper w, Class<T> iface) {\n    try {\n        return iface.isInstance(w) ? Optional.of(iface.cast(w))\n             : w.isWrapperFor(iface) ? Optional.of(w.unwrap(iface))\n             : Optional.empty();\n    } catch (SQLException e) { return Optional.empty(); }\n}","tryCatchPattern":"try {\n    NativeConnection n = conn.unwrap(NativeConnection.class);\n} catch (SQLException e) {\n    if (e.getMessage().startsWith(\"Not a wrapper for\")) {\n        // fall back to pure JDBC APIs\n    } else throw e;\n}","preventionTips":["Call isWrapperFor() before unwrap()","Design integration code against java.sql interfaces, not vendor classes","Check the pool's documented wrapper/delegation policy before relying on unwrap","Use pool configuration to expose native handles if vendor features are mandatory"],"tags":["jdbc","wrapper","unwrap","driver-compatibility"],"backgroundTag":"jdbc-unwrap-unsupported","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}