{"record":{"id":"dfd3303d308f44b1","repo":"alibaba/canal","slug":"no-such-method","errorCode":null,"errorMessage":"No such method: '{}' @ {}","messagePattern":"No such method: '(.+?)' @ (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java","lineNumber":123,"sourceCode":"            } catch (ClassNotFoundException e) {\r\n                // com.mysql.jdbc.Connection not found.\r\n            } catch (SQLException e) {\r\n                logger.warn(\"Unwrap \" + conn.getClass().getName() + \" to \" + connClazz.getName() + \" failed: \"\r\n                            + e.getMessage(),\r\n                    e);\r\n            }\r\n\r\n            return null;\r\n        }\r\n        return conn;\r\n    }\r\n\r\n    private static final Object invokeMethod(Object obj, Class<?> objClazz, String name) {\r\n        try {\r\n            Method method = objClazz.getMethod(name, (Class<?>[]) null);\r\n            return method.invoke(obj, (Object[]) null);\r\n        } catch (NoSuchMethodException e) {\r\n            throw new IllegalArgumentException(\"No such method: \\'\" + name + \"\\' @ \" + objClazz.getName(), e);\r\n        } catch (IllegalAccessException e) {\r\n            throw new IllegalArgumentException(\"Cannot invoke method: \\'\" + name + \"\\' @ \" + objClazz.getName(), e);\r\n        } catch (InvocationTargetException e) {\r\n            throw new IllegalArgumentException(\"Invoke method failed: \\'\" + name + \"\\' @ \" + objClazz.getName(),\r\n                e.getTargetException());\r\n        }\r\n    }\r\n\r\n    private static final Object getDeclaredField(Object obj, Class<?> objClazz, String name) {\r\n        try {\r\n            Field field = objClazz.getDeclaredField(name);\r\n            field.setAccessible(true);\r\n            return field.get(obj);\r\n        } catch (NoSuchFieldException e) {\r\n            throw new IllegalArgumentException(\"No such field: \\'\" + name + \"\\' @ \" + objClazz.getName(), e);\r\n        } catch (IllegalAccessException e) {\r\n            throw new IllegalArgumentException(\"Cannot get field: \\'\" + name + \"\\' @ \" + objClazz.getName(), e);\r\n        }\r","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java#L105-L141","documentation":"Thrown by the private reflection helper invokeMethod() in DirectLogFetcher when objClazz.getMethod(name) raises NoSuchMethodException. The library uses reflection to reach into the mysql driver's undocumented classes (ConnectionImpl / its IO) during open(), so this signals the driver's internal method surface has changed or the wrong class was passed.","triggerScenarios":"invokeMethod(obj, objClazz, name) is called against a mysql driver class whose API no longer declares a no-arg method 'name' (or the class resolved is a different one than the driver build the library was written against).","commonSituations":"Upgrading mysql-connector-java (e.g. 5.1 -> 8.x) renames or removes internal connection methods; running against a driver fork or a shaded/relocated driver; passing a proxy/wrapper class instead of the real ConnectionImpl.","solutions":["Check the message for the exact class + method name, then compare against the actual mysql-connector-java version on the classpath.","Pin mysql-connector-java to a 5.1.x release that still exposes com.mysql.jdbc.ConnectionImpl and its expected methods.","If you must use driver 8.x, switch to a dbsync/connector build that targets the 8.x internal layout (com.mysql.cj.jdbc.JdbcConnection) instead of relying on this fork's reflection.","Ensure no shading/relocation is stripping or renaming the driver classes fetched reflectively."],"exampleFix":"// before - relies on driver internals\nClass<?> connClazz = Class.forName(\"com.mysql.jdbc.ConnectionImpl\");\nObject connIo = getDeclaredField(unwrapConn, connClazz, \"io\");\n\n// after - pin compatible driver in pom\n<!-- mysql-connector-java 5.1.x exposes ConnectionImpl; avoid 8.x for this fork -->","handlingStrategy":"try-catch","validationCode":"// Verify the driver class exposes the expected method before relying on it\nClass<?> c = Class.forName(\"com.mysql.jdbc.ConnectionImpl\");\nboolean ok = false;\nfor (java.lang.reflect.Method m : c.getMethods()) {\n    if (m.getName().equals(\"getIO\") && m.getParameterCount() == 0) { ok = true; break; }\n}\nif (!ok) throw new IllegalStateException(\"driver missing expected ConnectionImpl method\");","typeGuard":null,"tryCatchPattern":"try {\n    fetcher.open(conn, file, pos, serverId, false);\n} catch (IllegalArgumentException e) { // wrapped NoSuchMethodException\n    throw new IOException(\"mysql driver method surface mismatch - pin connector/j 5.1.x\", e);\n}","preventionTips":["Pin mysql-connector-java to a 5.1.x version whose internal API matches this dbsync fork.","Run a startup probe that loads com.mysql.jdbc.ConnectionImpl before entering replication.","Avoid shaded/relocated driver artifacts that break the reflective lookups."],"tags":["binlog","reflection","driver-compat","mysql"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}