protobuf 2.5.0問題

   線上一個項目須要操做hdfs和hive,在使用時報以下錯誤:java

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中這個方法的定義以下:
node

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

而在2.5.0中:
apache

  //@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的包裏面:
tomcat

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版本的bash

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,致使會報錯。maven

根據ide

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

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

在 tomcat 5-7 jar包是按字母順序加載的,所以若是要想使protobuf-java-2.4.0a.jar先於hive-exec-0.13.1.jar加載,能夠更改protobuf-java-2.4.0a.jar的文件名。google

相關文章
相關標籤/搜索