apache/shardingsphere · error · IllegalStateException

Can not locate agent jar file by URL `%s`.

Error message

Can not locate agent jar file by URL `%s`.

What it means

Thrown by the Firebird frontend when a client issues a rollback referencing a transaction handle that the proxy's FirebirdTransactionIdGenerator does not consider active for the current connection. The proxy tracks Firebird transaction IDs per connection; a handle that was never opened, was already closed (committed/rolled back), or belongs to another connection is rejected with InvalidTransactionHandleException. It protects the proxy from operating on stale or foreign transaction state.

Source

Thrown at agent/core/src/main/java/org/apache/shardingsphere/agent/core/path/AgentPath.java:54

    /**
     * Get agent root path.
     *
     * @param classLoader classLoader
     * @return agent root path
     */
    public static File getRootPath(final ClassLoader classLoader) {
        String classResourcePath = String.join("", AgentPath.class.getName().replaceAll("\\.", "/"), ".class");
        URL resource = Objects.requireNonNull(classLoader.getResource(classResourcePath), "Can not locate agent jar file.");
        return getJarFile(resource.toString()).getParentFile();
    }
    
    private static File getJarFile(final String url) {
        try {
            File result = new File(new URL(url.substring(url.indexOf("file:"), url.indexOf('!'))).toURI());
            AgentPreconditions.checkState(result.exists(), String.format("Can not locate agent jar file by URL `%s`.", url));
            return result;
        } catch (final MalformedURLException | URISyntaxException ex) {
            throw new IllegalStateException(String.format("Can not locate agent jar file by URL `%s`.", url), ex);
        }
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Make the client always use the handle returned by the most recent Firebird start-transaction (OK packet) response and discard it after commit or rollback.
  2. Ensure the client does not send rollback twice for the same transaction handle; after the first rollback the handle is closed.
  3. If a connection was reconnected/reset, start a new transaction instead of reusing a handle obtained before the reset.
  4. Check proxy logs for the handle value in the message ('Invalid transaction handle: %d') and compare it against the handles the FirebirdTransactionIdGenerator issued for that connection id.

Example fix

// before (client pseudo-code)
conn.rollback(cachedTxHandle); // handle from a previous transaction

// after
int txHandle = conn.startTransaction(); // handle from start-transaction response
// ... work ...
conn.rollback(txHandle); // same, still-active handle
txHandle = -1; // never reuse
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: track the handle returned by start-transaction and clear it on terminal ops
if (txHandle < 0) throw new IllegalStateException("No active transaction to roll back");
conn.rollback(txHandle);
txHandle = -1;

Try / catch

// Server-side executor callers already map InvalidTransactionHandleException to a Firebird error packet;
// clients should treat it as fatal for the transaction and start a new one:
try {
    conn.rollback(txHandle);
} catch (InvalidTransactionHandleException e) {
    txHandle = -1; // discard stale handle
    log.warn("Stale Firebird transaction handle discarded", e);
}

Prevention

When it happens

Trigger: Executing FirebirdRollbackTransactionCommandExecutor with a packet transaction id that fails FirebirdTransactionIdGenerator.isTransactionActive(connectionId, handle): rolling back twice with the same handle, rolling back after the transaction was already closed, using a handle from a previous/other connection session, or a client that fabricates or caches stale transaction ids.

Common situations: Firebird client drivers that reuse transaction handles across transactions; connection pooling where a pooled connection resumes with a handle from an earlier session; client library version that does not consume the handle returned by the proxy's start-transaction response; interleaved transactions on one connection.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/419cf870a29c9166. Report an issue: GitHub.