не удалось найти неявное значение для параметра доказательства типа org.apache.flink.api.common.typeinfo.TypeInformation []

Я пытаюсь написать несколько вариантов использования Apache Flink. Одна ошибка, с которой я сталкиваюсь довольно часто:

could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[SomeType]

Моя проблема в том, что я не могу точно определить, когда они случаются, а когда нет.

Самым последним примером этого может быть следующий

...
val largeJoinDataGen = new LargeJoinDataGen(dataSetSize, dataGen, hitRatio)
val see = StreamExecutionEnvironment.getExecutionEnvironment
val newStreamInput = see.addSource(largeJoinDataGen)
...

где LargeJoinDataGen extends GeneratorSource[(Int, String)] и GeneratorSource[T] extends SourceFunction[T], оба определены в отдельных файлах.

Пытаясь построить это, я получаю

Error:(22, 39) could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[(Int, String)]
val newStreamInput = see.addSource(largeJoinDataGen)

1. Почему в данном примере ошибка?

2. Какими будут общие рекомендации при возникновении таких ошибок и как их избежать в будущем?

P.S .: первый проект scala и первый проект flink, так что проявите терпение


person jheyd    schedule 20.06.2016    source источник


Ответы (3)


В основном это происходит, когда у вас есть пользовательский код, то есть источник или функция карты или что-то в этом роде, имеющее общий параметр. В большинстве случаев вы можете исправить это, добавив что-то вроде

implicit val typeInfo = TypeInformation.of(classOf[(Int, String)])

Если ваш код находится внутри другого метода, который имеет универсальный параметр, вы также можете попробовать добавить контекст, привязанный к универсальному параметру метода, как в

def myMethod[T: TypeInformation](input: DataStream[Int]): DataStream[T] = ...
person aljoscha    schedule 20.06.2016
comment
это решение, похоже, работает. вызов метода - TypeInformation.of(classOf[(Int, String)]), вы можете исправить это в своем ответе. - person jheyd; 21.06.2016

Вы можете сделать импорт вместо имплицитов

import org.apache.flink.streaming.api.scala._

Это тоже поможет.

person dmreshet    schedule 02.06.2017
comment
Этот ответ является лучшим, потому что он позволяет избежать неявного создания TypeInformation, если процесс мигания сложен :) - person Thomas; 16.04.2018
comment
Почему это работает? импорт всего из пакета кажется анти-паттерном - person Justin Lin; 24.06.2019
comment
Почему у меня не работает? У меня import org.apache.flink.streaming.api.scala._, но эта ошибка все еще появляется. Пользуюсь flink 1.12.2. - person Jason Lee; 23.03.2021
comment
Странно, объект пакета выглядит точно так же в 1.11.3, который работает, а 1.12.3 не работает. - person Rajish; 15.05.2021

Моя проблема в том, что я не могу точно определить, когда они случаются, а когда нет.

Они случаются, когда неявный параметр обязательно. Если мы посмотрим на определение метода, мы увидим:

def addSource[T: TypeInformation](function: SourceFunction[T]): DataStream[T]

Но мы не видим никаких неявных параметров, где он?

Когда вы видите полиморфный метод, в котором параметр типа имеет форму

def foo[T : M](param: T)

Где T - параметр типа, а M - контекстная привязка . Это означает, что создатель метода запрашивает неявный параметр типа M[T]. Это эквивалентно:

def foo[T](param: T)(implicit ev: M[T])

В случае вашего метода он фактически расширен до:

def addSource[T](function: SourceFunction[T])(implicit evidence: TypeInformation[T]): DataStream[T]

Вот почему вы видите жалобы компилятора, поскольку он не может найти неявный параметр, который требуется методу.

Если мы зайдем в Apache Flink Wiki, в разделе Введите информацию, мы можем понять, почему это происходит:

Отсутствие неявного значения для доказательства ошибки параметра

В случае, когда TypeInformation не может быть создан, программы не могут быть скомпилированы с сообщением об ошибке «не удалось найти неявное значение для параметра свидетельства типа TypeInformation». Частая причина, если это код, который генерирует TypeInformation не был импортирован. Обязательно импортируйте весь пакет flink.api.scala. импортировать org.apache.flink.api.scala._

Для общих методов вам необходимо потребовать, чтобы они также генерировали TypeInformation на сайте вызова:

Для универсальных методов типы данных параметров функции и возвращаемого типа могут быть разными для каждого вызова и неизвестны на сайте, где определен метод. Приведенный выше код приведет к ошибке, что недостаточно неявных доказательств. В таких случаях информация о типе должна быть сгенерирована на сайте вызова и передана методу. Scala предлагает для этого неявные параметры.

Обратите внимание, что import org.apache.flink.streaming.api.scala._ также может быть необходимо.

Для ваших типов это означает, что если вызывающий метод является универсальным, ему также необходимо запросить контекстную привязку для параметра типа.

person Yuval Itzchakov    schedule 20.06.2016
comment
org.apache.flink.api.scala._ уже был импортирован, и это все еще происходит. Это то, что я имел в виду под словом «не могу пригвоздить». - person jheyd; 21.06.2016
comment
@jheyd Требовать, чтобы GeneratorSource[T] и SourceFunction[T] также имели границы контекста: GeneratorSource[T : TypeInformation], SourceFunction[T : TypeInformation] - person Yuval Itzchakov; 21.06.2016
comment
SourceFunction - это java-интерфейс, необходимый для метода addSource, добавление контекстных границ в GeneratorSource ничего не изменило. - person jheyd; 21.06.2016
comment
@jheyd Тогда, возможно, он должен быть доступен в более широком масштабе. Является ли метод вызова tge flink API общим? - person Yuval Itzchakov; 21.06.2016
comment
import org.apache.flink.api.scala._ у меня работает, большое спасибо - person Cyanny; 09.05.2017