{"record":{"id":"540ba95d5cdc9b72","repo":"alibaba/canal","slug":"cannot-invoke-method","errorCode":null,"errorMessage":"Cannot invoke method: '{}' @ {}","messagePattern":"Cannot invoke method: '(.+?)' @ (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java","lineNumber":125,"sourceCode":"            } 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\n    }\r\n\r","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java#L107-L143","documentation":"Thrown by invokeMethod() when Method.invoke raises IllegalAccessException. The helper does NOT call setAccessible(true) on methods (unlike getDeclaredField), so any non-public method, a Java module that denies access, or an active SecurityManager will trip this.","triggerScenarios":"invokeMethod resolves a method via getMethod but invoking it is forbidden: the method is package-private/protected, the JVM runs under a SecurityManager, or a JPMS module boundary blocks reflective invocation.","commonSituations":"Running dbsync under a restrictive container/agent with a SecurityManager, on Java 9+ where the mysql driver is not 'open' to dbsync, or against a driver version that changed a method's access modifier.","solutions":["Add the driver module to --add-opens (e.g. --add-opens java.base/java.lang=ALL-UNNAMED) or open the mysql driver package to dbsync.","Remove/disable the SecurityManager if it is not required for the deployment.","Pin to a mysql-connector-java version whose internal methods are public and match the reflection targets.","If you control the build, patch invokeMethod to call method.setAccessible(true) before invoke."],"exampleFix":"// before\nMethod method = objClazz.getMethod(name, (Class<?>[]) null);\nreturn method.invoke(obj, (Object[]) null);\n\n// after - force accessibility like getDeclaredField does\nMethod method = objClazz.getMethod(name, (Class<?>[]) null);\nmethod.setAccessible(true);\nreturn method.invoke(obj, (Object[]) null);","handlingStrategy":"validation","validationCode":"// Check the JVM will allow reflective invocation before opening\njava.lang.reflect.Method m = connClazz.getMethod(\"someMethod\");\ntry { m.setAccessible(true); }\ncatch (SecurityException se) { throw new IllegalStateException(\"JVM blocks reflective access - add --add-opens\", se); }","typeGuard":null,"tryCatchPattern":"try { fetcher.open(conn, file, pos, serverId, false); }\ncatch (IllegalArgumentException e) {\n    if (e.getCause() instanceof IllegalAccessException)\n        throw new IOException(\"module/security blocks driver reflection\", e);\n    throw e;\n}","preventionTips":["On Java 9+, add the necessary --add-opens for the mysql driver module.","Disable the SecurityManager if reflective driver access is required.","Patch invokeMethod to call setAccessible(true) if you control the build."],"tags":["binlog","reflection","module-system","securitymanager"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}