在apache flink的protobuf事件中反序列化事件

1aaf6o9v  于 2021-06-24  发布在  Flink
关注(0)|答案(1)|浏览(880)

我正在我的flink应用程序中阅读来自kinesis的事件。这些事件是protobuf格式的。如果我使用 'com.google.protobuf:protobuf-java:3.7.1' 在flink应用程序中我没有问题。但是如果我把它改成 'com.google.protobuf:protobuf-java:3.10.0' 我得到上面的堆栈跟踪异常

java.lang.IncompatibleClassChangeError: class com.google.protobuf.Descriptors$OneofDescriptor has interface com.google.protobuf.Descriptors$GenericDescriptor as super class
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetPublicMethods(Class.java:2902)
        at java.lang.Class.privateGetPublicMethods(Class.java:2917)
        at java.lang.Class.getMethods(Class.java:1615)
        at org.apache.flink.api.java.typeutils.TypeExtractor.isValidPojoField(TypeExtractor.java:1786)
        at org.apache.flink.api.java.typeutils.TypeExtractor.analyzePojo(TypeExtractor.java:1856)
        at org.apache.flink.api.java.typeutils.TypeExtractor.privateGetForClass(TypeExtractor.java:1746)
        at org.apache.flink.api.java.typeutils.TypeExtractor.privateGetForClass(TypeExtractor.java:1643)
        at org.apache.flink.api.java.typeutils.TypeExtractor.createTypeInfoWithTypeHierarchy(TypeExtractor.java:921)
        at org.apache.flink.api.java.typeutils.TypeExtractor.privateCreateTypeInfo(TypeExtractor.java:781)
        at org.apache.flink.api.java.typeutils.TypeExtractor.createTypeInfo(TypeExtractor.java:735)
        at org.apache.flink.api.java.typeutils.TypeExtractor.createTypeInfo(TypeExtractor.java:731)
        at org.apache.flink.api.common.typeinfo.TypeInformation.of(TypeInformation.java:211)
        at org.apache.flink.api.java.typeutils.ListTypeInfo.<init>(ListTypeInfo.java:45)
        at com.bagi.streaming.serialization.ProtoSchema.getProducedType(ProtoSchema.java:40)
        at org.apache.flink.streaming.connectors.kinesis.serialization.KinesisDeserializationSchemaWrapper.getProducedType(KinesisDeserializationSchemaWrapper.java:57)
        at org.apache.flink.streaming.connectors.kinesis.FlinkKinesisConsumer.getProducedType(FlinkKinesisConsumer.java:363)
        at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.addSource(StreamExecutionEnvironment.java:1456)
        at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.addSource(StreamExecutionEnvironment.java:1414)
        at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.addSource(StreamExecutionEnvironment.java:1396)
        at com.bagi.streaming.StreamProcessor.getKinesisTrackingStream(StreamProcessor.java:101)
        at com.bagi.streaming.StreamProcessor.getKinesisTrackingStream(StreamProcessor.java:110)
        at com.bagi.streaming.StreamProcessor.consumeKinesis(StreamProcessor.java:117)
        at com.bagi.streaming.StreamProcessor.main(StreamProcessor.java:80)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:529)
        at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:421)
        at org.apache.flink.client.program.ClusterClient.run(ClusterClient.java:423)
        at org.apache.flink.client.cli.CliFrontend.executeProgram(CliFrontend.java:813)
        at org.apache.flink.client.cli.CliFrontend.runProgram(CliFrontend.java:287)
        at org.apache.flink.client.cli.CliFrontend.run(CliFrontend.java:213)
        at org.apache.flink.client.cli.CliFrontend.parseParameters(CliFrontend.java:1050)
        at org.apache.flink.client.cli.CliFrontend.lambda$main$11(CliFrontend.java:1126)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1844)
        at org.apache.flink.runtime.security.HadoopSecurityContext.runSecured(HadoopSecurityContext.java:41)
        at org.apache.flink.client.cli.CliFrontend.main(CliFrontend.java:1126)

我正在使用flink@1.8.0 以及 'com.twitter:chill-protobuf:0.9.3' . 我正在我的mac上本地构建flink应用程序jar。我已经尝试过在3.10.0和3.7.1版本中使用protoc,以便在3.10.0版本中使用protobufjava。
这是我的反序列化程序

public class ProtoSchema implements DeserializationSchema<List<Event>> {

    @Override
    public List<Event> deserialize(byte[] message) throws IOException {

        List<Event> events = new LinkedList<>();
        InputStream inputStream = new ByteArrayInputStream(message);

        while (true) {
            Event event = Event.parseDelimitedFrom(inputStream);
            if (event != null) {
                events.add(event);
            } else {
                break;
            }
        }
        return events;
    }

    @Override
    public boolean isEndOfStream(List<Event> nextElement) {
        return false;
    }

    @Override
    public TypeInformation<List<Event>> getProducedType() {
        return new ListTypeInfo<>(Event.class);
    }
}

我正在插入

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

Properties consumerConfig = new Properties();
consumerConfig.put(AWSConfigConstants.AWS_CREDENTIALS_PROVIDER, "AUTO");
consumerConfig.put(AWSConfigConstants.AWS_REGION, region);
consumerConfig.put(ConsumerConfigConstants.SHARD_GETRECORDS_INTERVAL_MILLIS, "300");
consumerConfig.put(ConsumerConfigConstants.SHARD_GETRECORDS_RETRIES, "10");
consumerConfig.put(ConsumerConfigConstants.SHARD_GETRECORDS_MAX, "5000");
consumerConfig.put(ConsumerConfigConstants.STREAM_INITIAL_POSITION, "LATEST");

env.addSource(new FlinkKinesisConsumer<>(name, new ProtoSchema(), consumerConfig)).name("KinesisSource");
env.getConfig().registerTypeWithKryoSerializer(Event.class, ProtobufSerializer.class);

使用protobuf模式编译event.classprotoc@3.10.0 以及protobuf-java@3.10.0

omhiaaxx

omhiaaxx1#

正如你在评论中所说 protobuf-java:3.9.0 较低版本(3.8-)存在二进制不兼容更改。
上课 class Descriptors.OneofDescriptor 添加了super class descriptors.genericdescriptor,客户端类的超级接口的静态字段可能会隐藏从新的超级类继承的字段(同名),并导致不兼容的ClassChangeError异常。更多
如果你在你的类路径上 protobuf-java:3.9.0+ 还有一些较低版本(3.8-)调用这个类你会得到这个错误(在我的例子中,它来自hadoop,它有2.5protobufjava版本,我的fatjar有3.10)
解决方案:
您需要对其中一个不兼容的依赖项进行着色 protobuf-java 更多如何用gradle来掩盖依赖性
或使用3.8及更低版本作为临时短视解决方案。

相关问题