我有一个抽象类,其抽象方法创建SourceFunction
,因此派生类可以返回简单或更复杂的源(例如KafkaConsumers
等)。 ChangeMe
是一个由AvroSchema编译创建的简单自动生成的类。
public SourceFunction<ChangeMe> createSourceFunction(ParameterTool params) {
FromElementsFunction<ChangeMe> dataSource = null;
List<ChangeMe> changeMeList = Arrays.asList(
ChangeMe.newBuilder().setSomeField("Some field 1").build(),
ChangeMe.newBuilder().setSomeField("Some field 2").build(),
ChangeMe.newBuilder().setSomeField("Some field 3").build()
);
try {
dataSource = new FromElementsFunction<>(new AvroSerializer<>(ChangeMe.class), changeMeList);
}
catch (IOException ex){
}
return dataSource;
}
在我的Flink工作中,我基本上有这个:
SourceFunction<ChangeMe> source = createSourceFunction(params);
DataStream<T> sourceDataStream = streamExecutionEnvironment.addSource(source);
DataStream<ChangeMe> changeMeEventsStream = this.getSourceDataStream(); // gets sourceDataStream above
changeMeEventsStream.print();
当我运行作业时,我对print()的调用出现了这个错误:
Exception in thread "main" org.apache.flink.api.common.functions.InvalidTypesException: The return type of function 'Custom Source' could not be determined automatically, due to type erasure. You can give type information hints by using the returns(...) method on the result of the transformation call, or by letting your function implement the 'ResultTypeQueryable' interface.
……
Caused by: org.apache.flink.api.common.functions.InvalidTypesException: Type of TypeVariable 'T' in 'class org.apache.flink.streaming.api.functions.source.FromElementsFunction' could not be determined. This is most likely a type erasure problem. The type extraction currently supports types with generic variables only in cases where all variables in the return type can be deduced from the input type(s).
我正在使用Eclipse编译器,所以我认为会包含类型信息(虽然我认为这只是为了lambda,而且上面没有)。我需要做些什么才能让它正常运行?
答案 0 :(得分:2)
如果要直接实例化FromElementsFunction
,则必须在调用TypeInformation
时为ChangeMe
类手动提供addSource
实例。这对于Flink了解元素类型是必要的。
以下代码段应该可以解决问题:
SourceFunction<ChangeMe> source = createSourceFunction();
TypeInformation<ChangeMe> typeInfo = TypeInformation.of(ChangeMe.class);
DataStream<ChangeMe> sourceDataStream = env.addSource(source, typeInfo);
DataStream<ChangeMe> changeMeEventsStream = sourceDataStream;
changeMeEventsStream.print();