protobuf 2.5.0问题

线上一个项目需要操作hdfs和hive,在使用时报如下错误:

java.lang.UnsupportedOperationException: This is supposed to be overridden by subclasses.
        at com.google.protobuf.GeneratedMessage.getUnknownFields(GeneratedMessage.java:180)
        at org.apache.hadoop.hdfs.protocol.proto.HdfsProtos$FsPermissionProto.getSerializedSize(HdfsProtos.java:5407)
        at com.google.protobuf.CodedOutputStream.computeMessageSizeNoTag(CodedOutputStream.java:749)
        at com.google.protobuf.CodedOutputStream.computeMessageSize(CodedOutputStream.java:530)
        at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$CreateRequestProto.getSerializedSize(ClientNamenodeProtocolProtos.java:2371)
        at com.google.protobuf.AbstractMessageLite.toByteString(AbstractMessageLite.java:49)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.constructRpcRequest(ProtobufRpcEngine.java:149)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:193)
        at $Proxy28.create(Unknown Source)
        at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.create(ClientNamenodeProtocolTranslatorPB.java:193)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:164)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:83)
        at $Proxy29.create(Unknown Source)
        at org.apache.hadoop.hdfs.DFSOutputStream.<init>(DFSOutputStream.java:1325)
        at org.apache.hadoop.hdfs.DFSOutputStream.newStreamForCreate(DFSOutputStream.java:1344)
        at org.apache.hadoop.hdfs.DFSClient.create(DFSClient.java:1255)
        at org.apache.hadoop.hdfs.DFSClient.create(DFSClient.java:1212)
        at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:276)
        at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:265)
        at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:82)
        at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:886)

根据堆栈信息,可以看到是pb的问题,异常由com.google.protobuf.GeneratedMessage类的getUnknownFields方法抛出。
在2.4.0a中这个方法的定义如下:

    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public final UnknownFieldSet getUnknownFields() {
      return unknownFields; //会返回一个值
    }

而在2.5.0中:

  //@Override (Java 1.6 override semantics, but we must support 1.5)
  public UnknownFieldSet getUnknownFields() {
    throw new UnsupportedOperationException( //在180行可以看到这个方法直接返回一个错误
        "This is supposed to be overridden by subclasses.");
  }

即这个错误是由于pb的版本导致,项目是运行在tomcat容器下面的,在WEB-INF/lib目录下只发现protobuf-java-2.4.0a.jar的包,同时在整个文件系统中也只有这一个pb包,在删除这个pb包之后,错误仍然存在,也就是有可能pb已经打在别的jar包里面了。通过jar tvf,最终发现pb是在hive-exec的包里面:

jar tvf hive-exec-0.13.1.jar |grep protobuf
     0 Mon Jun 02 12:50:20 CST 2014 META-INF/maven/com.google.protobuf/
     0 Mon Jun 02 12:50:20 CST 2014 META-INF/maven/com.google.protobuf/protobuf-java/
   141 Mon Jun 02 12:50:20 CST 2014 META-INF/maven/com.google.protobuf/protobuf-java/pom.properties
  8375 Mon Jun 02 12:50:20 CST 2014 META-INF/maven/com.google.protobuf/protobuf-java/pom.xml
     0 Mon Jun 02 12:50:20 CST 2014 com/google/protobuf/
  1014 Mon Jun 02 12:50:20 CST 2014 com/google/protobuf/AbstractMessage$1.class
30034 Mon Jun 02 12:50:20 CST 2014 com/google/protobuf/AbstractMessage$Builder.class
  7979 Mon Jun 02 12:50:20 CST 2014 com/google/protobuf/AbstractMessage.class
...

同时解压jar之后,查看其pom.properties文件,发现是pb是2.5.0版本的

cd /usr/local/src/META-INF/maven/com.google.protobuf/protobuf-java
cat pom.properties
#Generated by org.apache.felix.bundleplugin
#Thu Mar 07 15:48:28 PST 2013
version=2.5.0
groupId=com.google.protobuf
artifactId=protobuf-java

尝试更改了hive的pom文件,把pb的依赖设置为2.4.0a时,编译不能通过,即cdh4.6.0是需要使用pb 2.4.x的,而hive0.13.1默认是使用2.5.0的,而项目默认加载了2.5.0的pb,导致会报错。

根据

http://stackoverflow.com/questions/5474765/order-of-loading-jar-files-from-lib-directory

https://issues.apache.org/bugzilla/show_bug.cgi?id=57129

在 tomcat 5-7 jar包是按字母顺序加载的,因此如果要想使protobuf-java-2.4.0a.jar先于hive-exec-0.13.1.jar加载,可以更改protobuf-java-2.4.0a.jar的文件名。

时间: 2024-10-24 11:53:12

protobuf 2.5.0问题的相关文章

Windows下编译protobuf v3.3.0

一:概述 关于 protobuf 在此不再多说,此处记录下成功编译步骤以备日后查阅.注意:本文并不是使用cmake gui进行编译的,如果熟悉cmake gui的话,也可以使用gui进行生成编译. 二:准备资源及工具 VS2013或以上版本,安装好 protobuf 源码,下载地址:官网:http://code.google.com/p/protobuf/git网:https://github.com/google/protobuf或git:https://github.com/google/p

Ubuntu16.04+cuda8.0+cuDNNV5.1 + Tensorflow+ GT 840M安装小结

最近重装系统,安装了tensorflow的配置环境 总结一下. 参考资料http://blog.csdn.net/ZWX2445205419/article/details/69429518http://blog.csdn.net/u013294888/article/details/56666023http://www.2cto.com/kf/201612/578337.htmlhttp://blog.csdn.net/10km/article/details/61915535 NVIDIA驱

在Android Studio配置google protobuf

1.在project的build.gradle中配置 buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' } } 注意 Gradle版本至少是 2.12 并且Java 7,本例子使用的是2.

hadoop 2.6.0源码编译

这里面选择的HADOOP的版本为2.6.编译前需要准备的如下工具: HADOOP:   hadoop-2.6.0-src.tar.gz JDK:   jdk-7u71-linux-x64.tar.gz MAVEN:  apache-maven-3.0.5-bin.tar.gz PROTOBUF:   protobuf-2.5.0.tar.gz FINDBUGS:    findbugs-3.0.0.tar.gz ANT:  apache-ant-1.9.4-bin.tar.gz 1.分别解压ha

protobuf c++入门

1.在.proto文件中定义消息格式 2.使用protobuf编译器 3.使用c++ api来读写消息 0.为何使用protobuf? 1.原始内存数据结构,可以以二进制方式sent/saved.这种方式需要相同的内存布局和字节序. 2.以ad-hoc方式将数据项编码成一个简单字符串----比如,将4个int类型编码成"12:3:-23:67".这种方式简灵活.适用于简单数据. 3.将数据序列化为XML.这种方式很流行,因为xml可读性好,编码解码方便,性能也好.仅仅XML dom树比

64位centos 下编译 hadoop 2.6.0 源码

64位os下为啥要编译hadoop就不解释了,百度一下就能知道原因,下面是步骤: 前提:编译源码所在的机器,必须能上网,否则建议不要尝试了 一. 下载必要的组件 a) 下载hadoop源码 (当前最新的稳定版是2.6.0)地址  http://mirrors.hust.edu.cn/apache/hadoop/common/stable/hadoop-2.6.0-src.tar.gz b) 下载apache-ant (centos自带的ant版本太低,编译过程中会报错)地址: http://mi

protobuf C++ 使用示例

1.在.proto文件中定义消息格式 2.使用protobuf编译器 3.使用c++ api来读写消息 0.为何使用protobuf? 1.原始内存数据结构,可以以二进制方式sent/saved.这种方式需要相同的内存布局和字节序. 2.以ad-hoc方式将数据项编码成一个简单字符串----比如,将4个int类型编码成"12:3:-23:67".这种方式简灵活.适用于简单数据. 3.将数据序列化为XML.这种方式很流行,因为xml可读性好,编码解码方便,性能也好.仅仅XML dom树比

nodejs的protoBuf使用

protobuf的使用: 项目地址:https://github.com/chrisdew/protobuf peed The Protobuf for Node add-on relies on the protobuf C++ runtime but it does not require any generation, compilation or linkage of generated C++ code. It works reflectively and is thus able t

protobuf 一个c++示例

http://wangjunle23.blog.163.com/blog/static/11783817120126155282640/ 1.在.proto文件中定义消息格式 2.使用protobuf编译器 3.使用c++ api来读写消息 0.为何使用protobuf? 1.原始内存数据结构,可以以二进制方式sent/saved.这种方式需要相同的内存布局和字节序. 2.以ad-hoc方式将数据项编码成一个简单字符串----比如,将4个int类型编码成"12:3:-23:67".这种