欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Hbase、elasticsearch整合中jar包冲突的问题解决

程序员文章站 2024-02-25 08:50:22
问题背景 再数据平台中,项目搭建需要使用es和hbase搭建数据查询接口,整合的过程中出现jar包冲突的bug :com.google.common.base.stopw...

问题背景

再数据平台中,项目搭建需要使用es和hbase搭建数据查询接口,整合的过程中出现jar包冲突的bug :com.google.common.base.stopwatch.()v from class org.apache.hadoop.hbase.zookeeper.metatablelocator

org.apache.hadoop.hbase.donotretryioexception: java.lang.illegalaccesserror: tried to access method com.google.common.base.stopwatch.<init>()v from class org.apache.hadoop.hbase.zookeeper.metatablelocator
    at org.apache.hadoop.hbase.client.rpcretryingcaller.translateexception(rpcretryingcaller.java:239)
    at org.apache.hadoop.hbase.client.rpcretryingcaller.callwithretries(rpcretryingcaller.java:150)
    ...
    at java.lang.thread.run(thread.java:745)
caused by: java.lang.illegalaccesserror: tried to access method com.google.common.base.stopwatch.<init>()v from class org.apache.hadoop.hbase.zookeeper.metatablelocator
    at org.apache.hadoop.hbase.zookeeper.metatablelocator.blockuntil
    ...
    at org.apache.hadoop.hbase.client.regionservercallable.prepare(regionservercallable.java:75)
    at org.apache.hadoop.hbase.client.rpcretryingcaller.callwithretries(rpcretryingcaller.java:134)
    ... 45 more

解决办法

经排查,确认是因为 com.google.guava 这个包引起的冲突。es依赖于18及以上版本,而hbase只支持16及以上版本。而guava这个包从17开始内部发生变化,方法发生改变,所以18并不会向下兼容16版本。在项目运行的过程中,如果同时引入16、18版本,es及hbase的调用过程会发生混乱。那么接下来就好办了,我们可以重新打包,将guava18打入es内部,再在pom文件中显示引用guava16版本的包。这样,es调用包内部打入的guava18,而hbase调用外部的guava16。

重新打包

新建maven工程,在pom文件中进行如下配置:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
     xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>

  <!--
    this maven project is aim to fix the jar comflic in hbase & elasticsearch.
    in es, required guava 18+ or up. but in hbase you should use guava 16- or blow.

    cd the project directory and run 'sh ./cleanbuild.sh',you will get a new-self jar.
    then, adjust your project pom.xml whth:
    <dependency>
      <groupid>douguo.shaded.elasticsearch</groupid>
      <artifactid>douguo_shaded_elasticsearch</artifactid>
      <version>1.0-snapshot</version>
      <exclusions>
        <exclusion>
          <groupid>org.elasticsearch</groupid>
          <artifactid>elasticsearch</artifactid>
        </exclusion>
      </exclusions>
    </dependency>
    finally, your jar comflic will be fixed.

    @date:2017-11-30
    @author:zhangjianfei
    @since:douguo.shaded.elasticsearch-1.0.0
  -->
  <groupid>douguo.shaded.elasticsearch</groupid>
  <artifactid>douguo_shaded_elasticsearch</artifactid>
  <version>1.0-snapshot</version>

  <properties>
    <elasticsearch.version>2.4.1</elasticsearch.version>
  </properties>
  <dependencies>
    <dependency>
      <groupid>org.elasticsearch</groupid>
      <artifactid>elasticsearch</artifactid>
      <version>${elasticsearch.version}</version>
    </dependency>
    <dependency>
      <groupid>org.elasticsearch.plugin</groupid>
      <artifactid>shield</artifactid>
      <version>${elasticsearch.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupid>org.apache.maven.plugins</groupid>
        <artifactid>maven-shade-plugin</artifactid>
        <version>2.4.1</version>
        <configuration>
          <createdependencyreducedpom>false</createdependencyreducedpom>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <relocations>
                <relocation>
                  <pattern>com.google.guava</pattern>
                  <shadedpattern>douguo.shaded.elasticsearch.guava</shadedpattern>
                </relocation>
                <relocation>
                  <pattern>org.joda</pattern>
                  <shadedpattern>douguo.shaded.elasticsearch.joda</shadedpattern>
                </relocation>
                <relocation>
                  <pattern>com.google.common</pattern>
                  <shadedpattern>douguo.shaded.elasticsearch.common</shadedpattern>
                </relocation>
                <relocation>
                  <pattern>com.google.thirdparty</pattern>
                  <shadedpattern>douguo.shaded.elasticsearch.thirdparty</shadedpattern>
                </relocation>
              </relocations>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.manifestresourcetransformer" />
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <repositories>
    <repository>
      <id>elasticsearch-releases</id>
      <url>http://maven.elasticsearch.org/releases</url>
      <releases>
        <enabled>true</enabled>
        <updatepolicy>daily</updatepolicy>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

</project>

将org.joda等4个可能有冲突的jar包通过maven-shade-plugin插件迁移后重新打个jar包从而使得在引入这个jar包时能够使用该jar包自己的依赖而不是使用外部依赖。这里需要注意的是,需要将com.google.common等4个包全部重新迁移,否则会出现java.lang.illegalaccesserror: tried to access method com.google.common.base的错误

项目打包

mvn clean install

新的依赖包会在.m2 maven仓库中,如果公司搭建了仓库的话,需要上传jar包。如果直接运行jar包的话,记得重新编译项目,并替换lib目录

项目载入新包

只需要在pom文件中配置:

<!-- douguo.shaded.elasticsearch -->
<dependency>
  <groupid>douguo.shaded.elasticsearch</groupid>
  <artifactid>douguo_shaded_elasticsearch</artifactid>
  <version>1.0-snapshot</version>
  <exclusions>
    <exclusion>
      <groupid>org.elasticsearch</groupid>
      <artifactid>elasticsearch</artifactid>
    </exclusion>
  </exclusions>
</dependency>


<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<!-- this guava is only used in habse
   in es, 18.0+ is required, but hbase only supported 16.0 or blow.
   clean as install douguo.shaded.elasticsearch -->
<dependency>
  <groupid>com.google.guava</groupid>
  <artifactid>guava</artifactid>
  <version>16.0</version>
</dependency>

这样,guava18包就在douguo.shaded.elasticsearch下,es会优先调用。而外部配置的guava16就会被hbase调用。2个版本的jar包互相独立存在!

到此,问题就解决了!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。