apache/seatunnel · error · InvocationTargetException

Proxy Connection is null.

Error message

Proxy Connection is null.

What it means

CopyManagerProxy unwraps the pooled/proxied JDBC Connection to reach the native connection needed for COPY. If the proxy's InvocationHandler cannot yield a real Connection (getConnectionFromInvocationHandler returns null), this error is thrown, since COPY requires the driver's native connection object.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/executor/CopyManagerProxy.java:50

    private static final Logger LOG = LoggerFactory.getLogger(CopyManagerProxy.class);
    Object connection;
    Object copyManager;
    Class<?> connectionClazz;
    Class<?> copyManagerClazz;
    Method getCopyAPIMethod;
    Method copyInMethod;

    CopyManagerProxy(Connection connection)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
                    SQLException {
        LOG.info("Proxy connection class: {}", connection.getClass().getName());
        this.connection = connection.unwrap(Connection.class);
        LOG.info("Proxy unwrap connection class: {}", this.connection.getClass().getName());
        if (Proxy.isProxyClass(this.connection.getClass())) {
            InvocationHandler handler = Proxy.getInvocationHandler(this.connection);
            this.connection = getConnectionFromInvocationHandler(handler);
            if (null == this.connection) {
                throw new InvocationTargetException(
                        new NullPointerException("Proxy Connection is null."));
            }
            LOG.info("Proxy connection class: {}", this.connection.getClass().getName());
            this.connectionClazz = this.connection.getClass();
        } else {
            this.connectionClazz = this.connection.getClass();
        }
        this.getCopyAPIMethod = this.connectionClazz.getMethod("getCopyAPI");
        this.copyManager = this.getCopyAPIMethod.invoke(this.connection);
        this.copyManagerClazz = this.copyManager.getClass();
        this.copyInMethod = this.copyManagerClazz.getMethod("copyIn", String.class, Reader.class);
    }

    long doCopy(String sql, Reader reader)
            throws InvocationTargetException, IllegalAccessException {
        return (long) this.copyInMethod.invoke(this.copyManager, sql, reader);
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Bypass the pool: obtain a raw connection from the driver for the copy executor.
  2. Upgrade SeaTunnel connector-jdbc, which may add support for your pool's proxy layout.
  3. Use a pool/driver combination known to work (e.g. HikariCP with the official PostgreSQL driver).
  4. Log the connection class and InvocationHandler type and check whether it is a supported wrapper.

Example fix

// before: passing pooled connection directly
Connection conn = dataSource.getConnection();
new CopyManagerProxy(conn);
// after: unwrap first where possible
Connection native = conn.unwrap(org.postgresql.PGConnection.class).getConnection(); // or pass unwrapped connection
Defensive patterns

Strategy: validation

Validate before calling

Connection c = dataSource.getConnection();
if (Proxy.isProxyClass(c.getClass())) {
  InvocationHandler h = Proxy.getInvocationHandler(c);
  // ensure handler exposes the native connection before using copy executor
  LOG.info("connection wrapper: {} / {}", c.getClass(), h.getClass());
}

Type guard

boolean isNativelyUnwrappable(Connection c) {
  try { c.unwrap(Connection.class); return true; } catch (SQLException e) { return false; }
}

Try / catch

try {
  new CopyManagerProxy(connection);
} catch (JdbcConnectorException | InvocationTargetException e) {
  // fall back to a non-copy statement executor for pooled/proxied connections
}

Prevention

When it happens

Trigger: Constructing CopyManagerProxy with a Connection from a connection pool (e.g. HikariCP, DBCP) whose proxy class/InvocationHandler does not expose the underlying native connection in the expected field.

Common situations: Using an unsupported pooling library or unusual driver wrapper in front of PostgreSQL; running inside a framework that wraps connections; driver upgrade changed internal proxy structure.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/95fa5ef1a4a60134. Report an issue: GitHub.