我有几个依赖的.proto文件syntax = "proto3";
.我还有一个Maven项目,用于构建Hadoop/Spark作业(Hadoop 2.7.1和Spark 1.5.2).我想在Hadoop/Spark中生成数据,然后根据我的proto3文件对其进行序列化.
使用libprotoc 3.0.0,我生成的Java源代码在我的Maven项目中工作正常,只要我在pom.xml中有以下内容:
com.google.protobuf protobuf-java 3.0.0-beta-1
现在,当我在一个部署到集群的作业中使用我的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依赖于protobuf-java 2.5.0,这与我的3.0.0-beta-1不兼容.我还注意到protobufs(大概是版本<3)已经在其他几个地方进入我的罐子:
$ 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
只需要重新定位protobuffers并且VerifyError就会消失:
com.google.protobuf shaded.com.google.protobuf
与Dranxo相同的解决方案,但具有sbt组装
assemblyShadeRules in assembly := Seq( ShadeRule.rename("com.google.protobuf.*" -> "shadedproto.@1").inProject .inLibrary("com.google.protobuf" % "protobuf-java" % protobufVersion) )