solr4.7.2整合hbase的BUG

来源:互联网 发布:360极速浏览器linux版 编辑:程序博客网 时间:2024/04/28 02:13

场景:solr的handler中,连接hbase获取数据

BUG:见https://issues.apache.org/jira/browse/HBASE-9867

主要是hbase-protocol-0.98.1-cdh5.1.0.jar的类引用了protobuf-java-2.5.0.jar,注意:solr4.7.2的自带jar中已经有了protobuf-java-2.5.0.jar,而且与hbase引用的版本一样,按理还说是不会有问题的,不过却出现了问题。

原因是solrcloud是一个osgi(动态编译)环境下,我们把它的加载器想象成类似于tomcat的加载器树,在这个加载器树上面加载literalByteString等等这些protobuf-java-2.5.0.jar里面的类无法成功或者正确的加载。

解决方法是:去掉solr自带包中:

hadoop-annotations-2.2.0.jar
hadoop-auth-2.2.0.jar
hadoop-common-2.2.0.jar
hadoop-hdfs-2.2.0.jar
protobuf-java-2.5.0.jar

这5个类,然后重新打包发布。

同样的问题还有个BUG:hbase-default.xml file seems to be for and old version of HBase ...报hbase版本不一致,其实不是,也是因为在osgi环境下,无法找到HBaseConfiguration类的加载器,需要指定加载器。

解决方法是:加上

Thread.currentThread().setContextClassLoader(HBaseConfiguration.class.getClassLoader());


详解(纯属个人分析):

solrCloud是一个osgi环境,是java上的动态模块系统,OSGi中的每个模块(bundle)都包含 Java 包和类。模块可以声明它所依赖的需要导入(import)的其它模块的 Java 包和类(通过 Import-Package),也可以声明导出(export)自己的包和类,供其它模块使用(通过 Export-Package)。也就是说需要能够隐藏和共享一个模块中的某些 Java 包和类。这是通过 OSGi 特有的类加载器机制来实现的。OSGi 中的每个模块都有对应的一个类加载器。它负责加载模块自己包含的 Java 包和类。当它需要加载 Java 核心库的类时(以 java 开头的包和类),它会代理给父类加载器(通常是启动类加载器)来完成。

solrCloud的handler机制是spiService Provider Interface 接口设计,方法中只提供接口,外部提供实现传入。

1、hbase-protocol-0.98.1-cdh5.1.0.jar和solrCloud handler模块都引用了第三方protobuf-java-2.5.0.jar,不在同一个分支的加载器(2个bundle)加载的java类无法相互访问。

2、Thread.currentThread().getContextClassLoader() 为null,找不到当前线程加载器,无法加载HBaseConfiguration,所以要设置Thread.currentThread().setContextClassLoader(HBaseConfiguration.class.getClassLoader());

0 0
原创粉丝点击