{"record":{"id":"dc67190b424a9ed9","repo":"alibaba/canal","slug":"no-such-field","errorCode":null,"errorMessage":"No such field: '{}' @ {}","messagePattern":"No such field: '(.+?)' @ (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java","lineNumber":138,"sourceCode":"            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\n    }\r\n\r\n    /**\r\n     * Connect MySQL master to fetch binlog.\r\n     */\r\n    public void open(Connection conn, String fileName, final int serverId) throws IOException {\r\n        open(conn, fileName, BIN_LOG_HEADER_SIZE, serverId, false);\r\n    }\r\n\r\n    /**\r\n     * Connect MySQL master to fetch binlog.\r\n     */\r\n    public void open(Connection conn, String fileName, final int serverId, boolean nonBlocking) throws IOException {\r\n        open(conn, fileName, BIN_LOG_HEADER_SIZE, serverId, nonBlocking);\r\n    }\r","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java#L120-L156","documentation":"Thrown by the private helper getDeclaredField() when objClazz.getDeclaredField(name) raises NoSuchFieldException. DirectLogFetcher reflects on undocumented mysql driver fields (io, mysqlOutput, mysqlInput on the connection/IO objects), so this means the expected field name is gone from the resolved driver class.","triggerScenarios":"getDeclaredField(obj, objClazz, name) is asked for a field the resolved mysql driver class no longer declares (e.g. 'io' on ConnectionImpl, 'mysqlOutput'/'mysqlInput' on MysqlIO). Typical during open() while wiring the raw IO streams.","commonSituations":"mysql-connector-java upgrade (5.1 -> 8.x) renamed/removed internal fields; a driver fork or shaded artifact; resolving a different class than expected due to classpath conflicts.","solutions":["Read the message for the class + field name and check whether that field still exists in your mysql-connector-java jar (javap on the class).","Pin mysql-connector-java to the 5.1.x line that this fork of dbsync was written against.","Eliminate multiple driver versions on the classpath so the reflected class is the one expected.","If migrating to driver 8.x is required, use a dbsync/connector revision updated for the cj-package internal field layout."],"exampleFix":"// before - field name hardcoded against old driver\nmysqlOutput = (OutputStream) getDeclaredField(connIo, connIo.getClass(), \"mysqlOutput\");\n\n// after - verify field exists, else fail fast with guidance\nField f;\ntry { f = connIo.getClass().getDeclaredField(\"mysqlOutput\"); }\ncatch (NoSuchFieldException nsf) {\n    throw new IOException(\"mysql driver layout changed: missing mysqlOutput on \"\n        + connIo.getClass().getName() + \" - pin connector/j 5.1.x\", nsf);\n}","handlingStrategy":"validation","validationCode":"// Confirm the reflected field still exists on the resolved driver class\njava.lang.reflect.Field f;\ntry { f = Class.forName(\"com.mysql.jdbc.ConnectionImpl\").getDeclaredField(\"io\"); }\ncatch (NoSuchFieldException | ClassNotFoundException nf) {\n    throw new IllegalStateException(\"driver layout incompatible - pin connector/j 5.1.x\", nf);\n}","typeGuard":null,"tryCatchPattern":"try { fetcher.open(conn, file, pos, serverId, false); }\ncatch (IllegalArgumentException e) {\n    if (e.getCause() instanceof NoSuchFieldException)\n        throw new IOException(\"mysql driver field layout changed\", e);\n    throw e;\n}","preventionTips":["Keep the driver version aligned with the dbsync fork's expectations (5.1.x).","Resolve classpath conflicts so only one driver version is present.","Run a build-time or startup smoke test that reflects on the expected fields."],"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"}