我有一个简单的案例类
case class KafkaContainer(key: String, payload: AnyRef)
然后我想通过生产者将其发送给kafka主题
val byteArrayStream = new ByteArrayOutputStream()
val output = AvroOutputStream.binary[KafkaContainer](byteArrayStream)
output.write(msg)
output.close()
val bytes = byteArrayStream.toByteArray
producer.send(new ProducerRecord("my_topic", msg.key, bytes))
这很好用
然后我尝试食用
Consumer.committableSource(consumerSettings, Subscriptions.topics("my_topic"))
.map { msg =>
val in: ByteArrayInputStream = new ByteArrayInputStream(msg.record.value())
val input: AvroBinaryInputStream[KafkaContainer] = AvroInputStream.binary[KafkaContainer](in)
val result: Option[KafkaContainer] = input.iterator.toSeq.headOption
input.close()
...
}.runWith(Sink.ignore)
,这对于有效负载中的任何类都可以很好地工作。
但是!如果有的话。消费者代码失败并
错误:(38,96)找不到证据参数的隐式值 类型 com.sksamuel.avro4s.FromRecord [test.messages.KafkaContainer] val输入:AvroBinaryInputStream [KafkaContainer] = AvroInputStream.binaryKafkaContainer
错误:(38,96)不够 方法二进制的参数:(隐式证据$ 21: com.sksamuel.avro4s.SchemaFor [test.messages.KafkaContainer], 隐性证据$ 22: com.sksamuel.avro4s.FromRecord [test.messages.KafkaContainer])com.sksamuel.avro4s.AvroBinaryInputStream [test.messages.KafkaContainer]。 未指定的价值参数证据$ 22。 val输入:AvroBinaryInputStream [KafkaContainer] = AvroInputStream.binaryKafkaContainer
如果我用...声明隐式
implicit val schemaFor: SchemaFor[KafkaContainer] = SchemaFor[KafkaContainer]
implicit val fromRecord: FromRecord[KafkaContainer] = FromRecord[KafkaContainer]
无法编译
错误:(58,71)找不到类型的惰性隐式值 com.sksamuel.avro4s.FromValue [Object] 隐式val fromRecord:FromRecord [KafkaContainer] = FromRecord [KafkaContainer]
错误:(58,71)没有足够的参数用于 方法lazyConverter:(隐式fromValue: shapeless.Lazy [com.sksamuel.avro4s.FromValue [Object]])shapeless.Lazy [com.sksamuel.avro4s.FromValue [Object]]。 未指定的值参数fromValue。 隐式val fromRecord:FromRecord [KafkaContainer] = FromRecord [KafkaContainer]
如果添加每个需要编译器的隐式
lazy implicit val fromValue: FromValue[Object] = FromValue[Object]
implicit val fromRecordObject: FromRecord[Object] = FromRecord[Object]
implicit val schemaFor: SchemaFor[KafkaContainer] = SchemaFor[KafkaContainer]
implicit val fromRecord: FromRecord[KafkaContainer] = FromRecord[KafkaContainer]
编译失败,并显示错误
错误:(58,69)宏扩展期间发生异常: java.lang.IllegalArgumentException:要求失败:需要案例 类但对象不在scala.Predef $ .require(Predef.scala:277) 在com.sksamuel.avro4s.FromRecord $ .applyImpl(FromRecord.scala:283) 隐式val fromRecordObject:FromRecord [Object] = FromRecord [Object]
但是如果我将AnyRef替换为某个类-不需要隐式,一切都会再次正常运行
答案 0 :(得分:0)
我使用Any数据类型遇到类似的问题。您必须指定此成员变量的有效类型,因为Any或AnyRef可以是任何东西。然后,使用“无形”或“无形”(另请参见Github Documentation)。 就我而言,它可以是String,Long,Double或null,因此使用shapeless可以做到:
case class DataContainer(name: String, value: Option[String:+:Long:+:Double:+:CNil])
这将在AVRO中转换为联合类型:
{
"name" : "value",
"type" : [ "null", "string", "long", "double" ]
}