问题:
- 问题: Flink Scala在进行从Connectors中读取数据时,调用createInput方法遇到隐式转换的报错
现象:
报错代码段:
// 获取flink环境
val flink = ExecutionEnvironment.getExecutionEnvironment
val inputBuilder = JDBCInputFormat
.buildJDBCInputFormat()
// 行类型
.setRowTypeInfo(new RowTypeInfo(BasicTypeInfo.STRING_TYPE_INFO))
.finish()
val souce = flink.createInput(inputBuilder) // !!!此处出现报错
souce.print()
Error:(70, 38) could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[org.apache.flink.types.Row]
val resultSet = flink.createInput(inputBuilder)
源码分析:
def createInput[T](inputFormat : org.apache.flink.api.common.io.InputFormat[T, _])
(implicit evidence$7 : scala.reflect.ClassTag[T], evidence$8 : org.apache.flink.api.common.typeinfo.TypeInformation[T])
: org.apache.flink.api.scala.DataSet[T] = { /* compiled code */ }
注意,在 createInput中使用了隐式转换,提取InputFormat中的ClassTag和TypeInformation,由于隐式转换需要编译器自行识别,此处无法扎到对应的包,因此会出现编译错误,要解决此方法,需要引入饮食转换的包即可。
import org.apache.flink.api.scala._
引入此包后问题得到解决,可以正常编译。
- 问题:flink在获取Batch时,遇到找不到实现类的问题
现象:
报错信息
Exception in thread "main" org.apache.flink.table.api.TableException: Create BatchTableEnvironment failed.
at org.apache.flink.table.api.scala.BatchTableEnvironment$.create(BatchTableEnvironment.scala:308)
at org.apache.flink.table.api.scala.BatchTableEnvironment$.create(BatchTableEnvironment.scala:269)
at FlinkTest$.main(FlinkTest.scala:151)
at FlinkTest.main(FlinkTest.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.flink.table.api.scala.internal.BatchTableEnvironmentImpl
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.apache.flink.table.api.scala.BatchTableEnvironment$.create(BatchTableEnvironment.scala:292)
... 3 more
报错代码:
// 获取flink环境
val flink = ExecutionEnvironment.getExecutionEnvironment
// 批量表环境变量
val tableEnv = BatchTableEnvironment.create(flink) // 此处报错
maven依赖
<!--公共依赖版本号-->
<properties>
<flink.version>1.9.0</flink.version>
<flink.scala.version>2.11</flink.scala.version>
</properties>
<dependencies>
<!--flink start-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-core</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-streaming-scala -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-scala -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-jdbc -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-jdbc_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-connector-kafka -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-connector-kafka -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-table-common -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-common</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-table-api-scala -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-scala_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-table-planner -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-clients -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
<!--flink end-->
</dependencies>
问题分析:
源码中BatchTableEnvironment的类为trait,需要找到其实现类BatchTableEnvironmentImpl,而BatchTableEnvironmentImpl在flink-table-planner_${flink.scala.version}包中实现。
package org.apache.flink.table.api.scala
trait BatchTableEnvironment extends java.lang.Object with org.apache.flink.table.api.TableEnvironment {
def registerFunction[T](name : scala.Predef.String, tf : org.apache.flink.table.functions.TableFunction[T])(implicit evidence$1 : org.apache.flink.api.common.typeinfo.TypeInformation[T]) : scala.Unit
def registerFunction[T, ACC](name : scala.Predef.String, f : org.apache.flink.table.functions.AggregateFunction[T, ACC])(implicit evidence$2 : org.apache.flink.api.common.typeinfo.TypeInformation[T], evidence$3 : org.apache.flink.api.common.typeinfo.TypeInformation[ACC]) : scala.Unit
def fromDataSet[T](dataSet : org.apache.flink.api.scala.DataSet[T]) : org.apache.flink.table.api.Table
def fromDataSet[T](dataSet : org.apache.flink.api.scala.DataSet[T], fields : org.apache.flink.table.expressions.Expression*) : org.apache.flink.table.api.Table
def registerDataSet[T](name : scala.Predef.String, dataSet : org.apache.flink.api.scala.DataSet[T]) : scala.Unit
def registerDataSet[T](name : scala.Predef.String, dataSet : org.apache.flink.api.scala.DataSet[T], fields : org.apache.flink.table.expressions.Expression*) : scala.Unit
def toDataSet[T](table : org.apache.flink.table.api.Table)(implicit evidence$4 : org.apache.flink.api.common.typeinfo.TypeInformation[T]) : org.apache.flink.api.scala.DataSet[T]
def toDataSet[T](table : org.apache.flink.table.api.Table, queryConfig : org.apache.flink.table.api.BatchQueryConfig)(implicit evidence$5 : org.apache.flink.api.common.typeinfo.TypeInformation[T]) : org.apache.flink.api.scala.DataSet[T]
def sqlUpdate(stmt : scala.Predef.String, config : org.apache.flink.table.api.BatchQueryConfig) : scala.Unit
def insertInto(table : org.apache.flink.table.api.Table, queryConfig : org.apache.flink.table.api.BatchQueryConfig, sinkPath : scala.Predef.String, sinkPathContinued : scala.Predef.String*) : scala.Unit
@scala.throws[scala.Exception]
override def execute(jobName : scala.Predef.String) : org.apache.flink.api.common.JobExecutionResult
override def connect(connectorDescriptor : org.apache.flink.table.descriptors.ConnectorDescriptor) : org.apache.flink.table.descriptors.BatchTableDescriptor
}
object BatchTableEnvironment extends scala.AnyRef {
def create(executionEnvironment : org.apache.flink.api.scala.ExecutionEnvironment) : org.apache.flink.table.api.scala.BatchTableEnvironment = { /* compiled code */ }
def create(executionEnvironment : org.apache.flink.api.scala.ExecutionEnvironment, tableConfig : org.apache.flink.table.api.TableConfig) : org.apache.flink.table.api.scala.BatchTableEnvironment = { /* compiled code */ }
}
找了下库依赖中无此包,因此导致编译器找不到,如下图:
BatchTableEnvironmentImpl包信息:
<artifactId>flink-table-planner_${scala.binary.version}</artifactId>
<name>flink-table-planner</name>
<description>
This module bridges Table/SQL API and runtime. It contains
all resources that are required during pre-flight and runtime
phase.
</description>
BatchTableEnvironmentImpl源码:
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.flink.table.api.scala.internal
import org.apache.flink.api.common.typeinfo.TypeInformation
import org.apache.flink.api.scala._
import org.apache.flink.table.api._
import org.apache.flink.table.api.internal.BatchTableEnvImpl
import org.apache.flink.table.api.scala.BatchTableEnvironment
import org.apache.flink.table.catalog.CatalogManager
import org.apache.flink.table.expressions.Expression
import org.apache.flink.table.functions.{AggregateFunction, TableFunction}
import _root_.scala.reflect.ClassTag
/**
* The implementation for a Scala [[BatchTableEnvironment]] that works
* with [[DataSet]]s.
*
* @param execEnv The Scala batch [[ExecutionEnvironment]] of the TableEnvironment.
* @param config The configuration of the TableEnvironment.
*/
class BatchTableEnvironmentImpl(
execEnv: ExecutionEnvironment,
config: TableConfig,
catalogManager: CatalogManager)
extends BatchTableEnvImpl(
execEnv.getJavaEnv,
config,
catalogManager)
with org.apache.flink.table.api.scala.BatchTableEnvironment {
override def fromDataSet[T](dataSet: DataSet[T]): Table = {
createTable(asQueryOperation(dataSet.javaSet, None))
}
override def fromDataSet[T](dataSet: DataSet[T], fields: Expression*): Table = {
createTable(asQueryOperation(dataSet.javaSet, Some(fields.toArray)))
}
override def registerDataSet[T](name: String, dataSet: DataSet[T]): Unit = {
registerTable(name, fromDataSet(dataSet))
}
override def registerDataSet[T](name: String, dataSet: DataSet[T], fields: Expression*): Unit = {
registerTable(name, fromDataSet(dataSet, fields: _*))
}
override def toDataSet[T: TypeInformation](table: Table): DataSet[T] = {
// Use the default batch query config.
wrap[T](translate(table))(ClassTag.AnyRef.asInstanceOf[ClassTag[T]])
}
override def toDataSet[T: TypeInformation](
table: Table, queryConfig: BatchQueryConfig): DataSet[T] = {
wrap[T](translate(table))(ClassTag.AnyRef.asInstanceOf[ClassTag[T]])
}
override def registerFunction[T: TypeInformation](name: String, tf: TableFunction[T]): Unit = {
registerTableFunctionInternal(name, tf)
}
override def registerFunction[T: TypeInformation, ACC: TypeInformation](
name: String,
f: AggregateFunction[T, ACC])
: Unit = {
registerAggregateFunctionInternal[T, ACC](name, f)
}
override def sqlUpdate(stmt: String, config: BatchQueryConfig): Unit = sqlUpdate(stmt)
override def insertInto(
table: Table,
queryConfig: BatchQueryConfig,
sinkPath: String,
sinkPathContinued: String*): Unit = insertInto(table, sinkPath, sinkPathContinued: _*)
}
解决方法:
- 重新编辑maven依赖库,确保包加载到依赖库: (推荐)
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-table-planner -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_${flink.scala.version}</artifactId>
<version>${flink.version}</version>
</dependency>
2. 手动添加lib依赖库 (不推荐)