提交Flink集群作业时出现NoSuchMethodError的问题排查求助
问题根因
报错本质是跨版本类方法签名不匹配:
- 集群端通过AppClassLoader加载的
OperatorStateStore类来自flink-dist_2.11-1.11.3.jar,该版本的类中不存在getSerializableListState(String)方法 - 调用该方法的
FlinkKafkaConsumerBase类来自作业缓存的用户依赖包,由ChildFirstClassLoader加载 - 关键版本差异:
OperatorStateStore.getSerializableListState方法是Flink 1.12.0版本才新增的接口,Flink 1.11.x全版本都没有这个方法。只要你使用的Kafka Connector是基于Flink 1.12及以上版本编译的,即使开发环境把Flink API版本对齐到1.11.3,只要Connector依赖没有降版匹配,就会持续触发该报错。
可落地的解决步骤
1. 精确对齐Kafka Connector版本
- 替换pom中
flink-connector-kafka_2.11依赖为与集群完全匹配的1.11.3版本,scala编译版本保持2.11,不得混用1.12+版本的Connector,也不得跨scala版本(如用2.12编译的Connector搭配2.11版本的集群) - 执行依赖排查命令
mvn dependency:tree | grep flink,排查所有传递引入的Flink核心类、Kafka Connector版本残留,对版本不匹配的间接依赖通过<exclusion>标签强制排除
2. 修正maven-shade-plugin打包规则
Flink集群已经在lib目录提供了所有核心类,用户作业包绝对不能打包Flink核心类,否则会被ChildFirstClassLoader优先加载,和集群端核心类形成版本冲突,具体配置规则:
- 将所有Flink核心依赖的作用域设置为
provided,避免被打入作业包,示例依赖声明:<dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_2.11</artifactId> <version>1.11.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-core</artifactId> <version>1.11.3</version> <scope>provided</scope> </dependency> - 配置shade插件的排除规则,过滤所有Flink核心类,插件参考配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <excludes> <exclude>org.apache.flink:*</exclude> <exclude>org.apache.flink.**</exclude> </excludes> </artifactSet> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> - 打包完成后解压作业jar,检查是否存在
org/apache/flink/api/common/state/OperatorStateStore.class这类Flink核心类,如果存在,说明shade规则未生效,需要调整排除范围直到核心类完全不被打入jar包。
3. 集群端校验
- 检查集群每个节点的
/opt/flink/lib目录,是否存在手动放入的高版本Kafka Connector或Flink核心类残留,如果有,全部移到其他目录,统一使用作业包内的匹配版本依赖 - 提交作业时保持默认类加载规则,不要强制开启父类加载优先模式
内容的提问来源于stack exchange,提问作者Alif Munim
相关产品推荐
相关产品推荐

