alibaba/canal · critical · IOException
Unable to load com.mysql.jdbc.ConnectionImpl
Error message
Unable to load com.mysql.jdbc.ConnectionImpl
What it means
Thrown in DirectLogFetcher.open()'s catch(ClassNotFoundException) when Class.forName("com.mysql.jdbc.ConnectionImpl") fails - the legacy driver class is not on the classpath. This is the canonical signal that the deployed mysql driver does not contain the old com.mysql.jdbc package.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java:196
// Get underlying IO streams for network communications.
Object connIo = getDeclaredField(unwrapConn, connClazz, "io");
if (connIo == null) {
throw new IOException("Get null field:" + conn.getClass().getName() + "#io");
}
mysqlOutput = (OutputStream) getDeclaredField(connIo, connIo.getClass(), "mysqlOutput");
mysqlInput = (InputStream) getDeclaredField(connIo, connIo.getClass(), "mysqlInput");
if (filePosition == 0) filePosition = BIN_LOG_HEADER_SIZE;
sendBinlogDump(fileName, filePosition, serverId, nonBlocking);
position = 0;
} catch (IOException e) {
close(); /* Do cleanup */
logger.error("Error on COM_BINLOG_DUMP: file = " + fileName + ", position = " + filePosition);
throw e;
} catch (ClassNotFoundException e) {
close(); /* Do cleanup */
throw new IOException("Unable to load com.mysql.jdbc.ConnectionImpl", e);
}
}
/**
* Put a byte in the buffer.
*
* @param b the byte to put in the buffer
*/
protected final void putByte(byte b) {
ensureCapacity(position + 1);
buffer[position++] = b;
}
/**
* Put 16-bit integer in the buffer.
*
* @param i16 the integer to put in the buffer
View on GitHub (pinned to 87be50e876)
Solutions
- Add mysql-connector-java 5.1.x to the classpath (it still ships com.mysql.jdbc.ConnectionImpl).
- If you must use driver 8.x, switch to a dbsync/connector revision that loads com.mysql.cj.jdbc.JdbcConnection instead.
- Verify with 'jar tf <driver>.jar | grep ConnectionImpl' whether the class is actually present.
- Resolve classpath conflicts so only one driver version is present and the legacy class is loadable.
Example fix
// before - driver 8.x on classpath, legacy class absent fetcher.open(conn, file, pos, serverId); // -> Unable to load com.mysql.jdbc.ConnectionImpl // after - pin a driver that still has the class <!-- pom.xml --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency>
Defensive patterns
Strategy: validation
Validate before calling
// Fail fast if the legacy driver class is absent
try { Class.forName("com.mysql.jdbc.ConnectionImpl"); }
catch (ClassNotFoundException e) {
throw new IllegalStateException("com.mysql.jdbc.ConnectionImpl missing - add mysql-connector-java 5.1.x", e);
} Try / catch
try { fetcher.open(conn, file, pos, serverId, false); }
catch (IOException e) {
if (e.getMessage().contains("Unable to load com.mysql.jdbc.ConnectionImpl"))
throw new IOException("driver 8.x on classpath - pin connector/j 5.1.x or use a cj-compatible build", e);
throw e;
} Prevention
- Depend on mysql-connector-java 5.1.x in your pom for this dbsync fork.
- Run a startup Class.forName probe to catch the missing class early.
- Avoid mixing driver 8.x onto the classpath.
When it happens
Trigger: open() runs Class.forName("com.mysql.jdbc.ConnectionImpl") and the JVM cannot resolve the class, so the catch block re-throws it as IOException("Unable to load com.mysql.jdbc.ConnectionImpl", e).
Common situations: mysql-connector-java 8.0+ on the classpath, where the legacy com.mysql.jdbc.ConnectionImpl was removed (the com.mysql.cj.jdbc package replaces it); driver jar excluded from the build; an incompatible driver fork; classpath/shading stripped the class.
Related errors
- No such method: '{}' @ {}
- No such field: '{}' @ {}
- Unable to unwrap {} to com.mysql.jdbc.ConnectionImpl
- Get null field:{}#io
- Invoke method failed: '{}' @ {}
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/6c4126ee947567ea.
Report an issue: GitHub.