HBase EndPoint加載失敗
概述
參考博客(http://blog.csdn.net/carl810224/article/details/52224441)編寫EndPoint協處理器,編寫完成後使用Maven打包(使用assembly插件,指定descriptorRefs值為jar-with-dependencies,將依賴的jar包也加進來),再將jar包上傳到HDFS上,然後使用添加協處理器到指定表:
disable ‘test_table‘ alter ‘test_table‘,METHOD=>‘table_att‘,‘coprocessor‘=>‘hdfs://nameservice:/sum.jar|com.hbase.demo.endpoint.SumEndPoint|100‘ enable ‘test_table‘ describe ‘test_table‘
卸載處理器:
alter ‘test_table‘,METHOD=>‘table_att_unset‘,NAME=>‘coprocessor$1‘
coprocessor$1表示第一個協處理,可以通過describe命令查看表加載的處理器信息。
使用alter添加endpoint之後,輸入decribe查看表信息,發現表信息中心增加了coprocessor字段,事實上這並不表示已經加載成功。然後運行client程序,報錯信息是
“hbase.ipc.CoprocessorRpcChannel:Call failed on IOException” “UnknownProtocolException:No registered coprocessor service foundfor name SumService in region test_table.......”
查看RegionServer日誌,發現錯誤信息是
“RegionCoprocessorHost:Failed to load coprocessor com.hbase.demo.endpoint.SumEndPoint” “java.lang.LinkageError:loader constraint violation in interface itable initialization:when resolving methodcom.hbase.demo.endpoint.SumEndPoint.getService()Lcom/google/protobuf/Service;... the class loader......
have different Class objects for the type obuf/Service;used in the signature...."
實際上協處理器並沒有加載成功。
為什麽沒有加載成功
“java.lang.LinkageError:loader constraint violation in interface itable initialization...”表示發生了jar包沖突,就是一個工程中不止1個jar包中包含了完全相同的類,JVM不確定應該使用哪個jar包,解決辦法就是直接刪除多余jar包(確保jar包其余類不會被工程使用)。由於使用Maven的assembly插件打包時,選擇了“jar-with-dependencies”的方式將依賴的所有jar包也打到了EndPoint中,在加載EndPoint時,EndPoint對應jar包中的類與HBase ClassPath中某個jar包對應的類完全相同,JVM不確定應該使用哪個Jar包,因此加載不成功。
怎麽加載成功
找到了原因,對應的解決方法就很簡單了,去掉Maven的assembly插件中的“jar-with-dependencies”選項,僅將SumEndPoint.java和Sum.java打到jar包中,然後重新加載就可以了。
最後,Hbase 1.2.0使用protobuf作為RPC協議,因此需要首先下載protobuf變異.proto文件生成對應的.java文件,下載地址:github.com/google/protobuf/releases,Hbase 1.2.0對應protoc-2.5.0-win32.zip。下載完成後,進入bin目錄,變異proto文件
proto --java_out=./ sum.proto
HBase EndPoint加載失敗