t8y2/dbx · error · SQLException

Not a wrapper for <iface name>

Error message

Not a wrapper for <iface name>

What it means

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.

Source

Thrown at agents/common/src/main/java/com/dbx/agent/JdbcConnectionPoolRegistry.java:1133

        @Override
        public int getLoginTimeout() {
            // Hikari waits this long for in-flight add tasks before closing its connection bag.
            long timeoutSeconds = (connectionTimeoutMillis + 999L) / 1_000L;
            return (int) Math.min(Integer.MAX_VALUE, Math.max(1L, timeoutSeconds));
        }

        @Override
        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
            return Logger.getLogger("com.dbx.agent.jdbc.pool");
        }

        @Override
        public <T> T unwrap(Class<T> iface) throws SQLException {
            if (iface.isInstance(this)) {
                return iface.cast(this);
            }
            throw new SQLException("Not a wrapper for " + iface.getName());
        }

        @Override
        public boolean isWrapperFor(Class<?> iface) {
            return iface.isInstance(this);
        }
    }

    private static final class JdbcCheckoutExecutor implements AutoCloseable {
        private final ExecutorService executor;
        private final ConnectionReleaseExecutor releaseExecutor;

        private JdbcCheckoutExecutor(int maximumConcurrentCheckouts, ConnectionReleaseExecutor releaseExecutor) {
            this.executor = boundedExecutor(maximumConcurrentCheckouts, "dbx-jdbc-checkout");
            this.releaseExecutor = releaseExecutor;
        }

        private Connection checkout(

View on GitHub (pinned to c0390bff16)

Solutions

  1. Avoid vendor-specific APIs on pooled connections, or configure the pool/tooling to use pure JDBC APIs
  2. If native access is required, obtain the physical connection through a supported hook rather than unwrap()
  3. Use isWrapperFor(iface) first to check support before calling unwrap()
  4. Wrap in try-catch and fall back to generic JDBC code paths

Example fix

// before
OracleConnection ora = conn.unwrap(OracleConnection.class);
// after
if (conn.isWrapperFor(OracleConnection.class)) {
    OracleConnection ora = conn.unwrap(OracleConnection.class);
} else {
    // use generic java.sql APIs
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!connection.isWrapperFor(OracleConnection.class)) {
    throw new UnsupportedOperationException("vendor API unavailable on pooled connection");
}

Type guard

static <T> Optional<T> tryUnwrap(Wrapper w, Class<T> iface) {
    try {
        return iface.isInstance(w) ? Optional.of(iface.cast(w))
             : w.isWrapperFor(iface) ? Optional.of(w.unwrap(iface))
             : Optional.empty();
    } catch (SQLException e) { return Optional.empty(); }
}

Try / catch

try {
    NativeConnection n = conn.unwrap(NativeConnection.class);
} catch (SQLException e) {
    if (e.getMessage().startsWith("Not a wrapper for")) {
        // fall back to pure JDBC APIs
    } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/a9cd9d755f7f0ce7. Report an issue: GitHub.