如何将 proto3 与 Hadoop/Spark 一起使用?
How can I use proto3 with Hadoop/Spark?
我有几个依赖于 syntax = "proto3";
的 .proto 文件。我还有一个 Maven 项目,用于构建 Hadoop/Spark 个作业(Hadoop 2.7.1 和 Spark 1.5.2)。我想在 Hadoop/Spark 中生成数据,然后根据我的 proto3 文件对其进行序列化。
使用 libprotoc 3.0.0,我生成 Java 源代码,只要我的 pom.xml 中包含以下内容,它们就可以在我的 Maven 项目中正常工作:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.0-beta-1</version>
</dependency>
现在,当我在部署到集群的作业中使用我的 libprotoc 生成的 类 时,我遇到了:
java.lang.VerifyError : class blah overrides final method mergeUnknownFields.(Lcom/google/protobuf/UnknownFieldSet;)Lcom/google/protobuf/GeneratedMessage$Builder;
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
ClassLoader 失败似乎是合理的,因为 Hadoop/Spark 依赖于与我的 3.0.0-beta-1 不兼容的 protobuf-java 2.5.0。我还注意到 protobufs(大概版本 < 3)已经在其他几个地方进入我的 jar:
$ jar tf target/myjar-0.1-SNAPSHOT.jar | grep protobuf | grep '/$'
org/apache/hadoop/ipc/protobuf/
org/jboss/netty/handler/codec/protobuf/
META-INF/maven/com.google.protobuf/
META-INF/maven/com.google.protobuf/protobuf-java/
org/apache/mesos/protobuf/
io/netty/handler/codec/protobuf/
com/google/protobuf/
google/protobuf/
我可以做些什么(Maven Shade?)来解决这个问题吗?
这里有类似的问题:Spark java.lang.VerifyError
原来这里记录了这件事:https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
只需重新定位原型缓冲区,VerifyError 就会消失:
<relocations>
<relocation>
<pattern>com.google.protobuf</pattern>
<shadedPattern>shaded.com.google.protobuf</shadedPattern>
</relocation>
</relocations>
与 Dranxo 的解决方案相同,但使用 sbt 程序集
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("com.google.protobuf.*" -> "shadedproto.@1").inProject
.inLibrary("com.google.protobuf" % "protobuf-java" % protobufVersion)
)
我有几个依赖于 syntax = "proto3";
的 .proto 文件。我还有一个 Maven 项目,用于构建 Hadoop/Spark 个作业(Hadoop 2.7.1 和 Spark 1.5.2)。我想在 Hadoop/Spark 中生成数据,然后根据我的 proto3 文件对其进行序列化。
使用 libprotoc 3.0.0,我生成 Java 源代码,只要我的 pom.xml 中包含以下内容,它们就可以在我的 Maven 项目中正常工作:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.0-beta-1</version>
</dependency>
现在,当我在部署到集群的作业中使用我的 libprotoc 生成的 类 时,我遇到了:
java.lang.VerifyError : class blah overrides final method mergeUnknownFields.(Lcom/google/protobuf/UnknownFieldSet;)Lcom/google/protobuf/GeneratedMessage$Builder;
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
ClassLoader 失败似乎是合理的,因为 Hadoop/Spark 依赖于与我的 3.0.0-beta-1 不兼容的 protobuf-java 2.5.0。我还注意到 protobufs(大概版本 < 3)已经在其他几个地方进入我的 jar:
$ jar tf target/myjar-0.1-SNAPSHOT.jar | grep protobuf | grep '/$'
org/apache/hadoop/ipc/protobuf/
org/jboss/netty/handler/codec/protobuf/
META-INF/maven/com.google.protobuf/
META-INF/maven/com.google.protobuf/protobuf-java/
org/apache/mesos/protobuf/
io/netty/handler/codec/protobuf/
com/google/protobuf/
google/protobuf/
我可以做些什么(Maven Shade?)来解决这个问题吗?
这里有类似的问题:Spark java.lang.VerifyError
原来这里记录了这件事:https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
只需重新定位原型缓冲区,VerifyError 就会消失:
<relocations>
<relocation>
<pattern>com.google.protobuf</pattern>
<shadedPattern>shaded.com.google.protobuf</shadedPattern>
</relocation>
</relocations>
与 Dranxo 的解决方案相同,但使用 sbt 程序集
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("com.google.protobuf.*" -> "shadedproto.@1").inProject
.inLibrary("com.google.protobuf" % "protobuf-java" % protobufVersion)
)