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
- 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.
- Ensure the client does not send rollback twice for the same transaction handle; after the first rollback the handle is closed.
- If a connection was reconnected/reset, start a new transaction instead of reusing a handle obtained before the reset.
- 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
- Store the handle from the start-transaction response in a single variable per connection; overwrite on begin, null out on commit/rollback.
- Never share or persist transaction handles across reconnects or pooled connection checkouts.
- Wrap terminal operations in try/finally so a handle is always consumed exactly once.
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
- Can not find field name `%s` in class %s.
- HiveServer2 in embedded mode has been deprecated by Apache H
- Truncated batch BLOB segment length
- Batch BLOB segment declares %d bytes, but only %d bytes rema
- Unknown blob information request type %d
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/419cf870a29c9166.
Report an issue: GitHub.