Flink 1.14.5迁移至1.18.1时Scala Bridge依赖异常排查
我正在将项目从Flink 1.14.5迁移到1.18.1,使用Scala API与SBT构建工具。在Windows 11本地运行Jar包时出现以下错误:
java.lang.NoClassDefFoundError: org/apache/flink/table/api/bridge/scala/StreamTableEnvironment$ Caused by: java.lang.ClassNotFoundException: org.apache.flink.table.api.bridge.scala.StreamTableEnvironment$
此前我为Scala Bridge依赖设置了"provided"作用域,配置如下:
val flinkScalaBridge = "org.apache.flink" %% "flink-table-api-scala-bridge" % flinkVersion % "provided"
项目可正常编译,但无法运行Jar任务;移除"provided"作用域后则可正常运行。
我的问题是:版本迁移中发生了什么变化?是否需要将Scala Bridge添加到Flink /lib目录(或直接取消provided作用域),还是有其他更合适的方案?
更新说明
Scala用户需要显式添加flink-table-api-scala或flink-table-api-scala-bridge依赖。
解答
版本迁移的核心变化
在Flink 1.18.x版本中,Scala Table API的桥接依赖不再包含在官方默认的集群分发包内。你用1.14.5时,这个依赖是Flink集群自带的,所以设置provided作用域完全没问题——编译时能找到依赖,运行时集群会自动提供。但1.18.x重构了Table API的依赖结构,把Scala相关的桥接组件从核心依赖里拆出来了,集群默认不再提供该依赖,这就是你本地运行时找不到类的根本原因。
可选解决方案
直接取消
provided作用域
把依赖配置里的% "provided"删掉,SBT就会把flink-table-api-scala-bridge及其传递依赖打包到你的业务Jar里。这种方式最适合本地调试或者独立运行Jar的场景,不用修改Flink的任何配置,唯一缺点是Jar包体积会略有增加。将依赖添加到Flink
/lib目录
如果是要部署到Flink集群运行,你可以下载对应版本的flink-table-api-scala-bridgeJar包,放到Flink安装目录的/lib文件夹下,同时保持依赖的provided作用域。这样集群运行时会自动加载这个依赖,你的业务Jar也不会出现冗余内容。用SBT Assembly插件做条件打包
要是想同时兼顾本地运行和集群部署,可以用SBT Assembly插件配置打包规则:本地运行时把这个依赖打进去,集群部署时排除。不过这种配置需要编写额外的插件规则,相对麻烦,适合有复杂打包需求的场景。
内容的提问来源于stack exchange,提问作者Niko

