关于org.apache.hadoop.hbase.DoNotRetryIOException: java.lang.IllegalAccessError

  最近在项目中集成hbase1.0.0和ElasticSearch2.3.3时出现了问题,今天我把其中一个比较尴尬的问题写下来,log中错误:

org.apache.hadoop.hbase.DoNotRetryIOException: java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.()V from class org.apache.hadoop.hbase.zookeeper.MetaTableLocator

  之前我在集成ES时,引入了架包com.google.guava(18.0版本),程序得以顺利执行。后来在集成HBase时发现它也用到了guava,且是12.0版本的。这时候问题来了,如果将原来的guava 18.0版本修改为16.0版本以下(HBase中用到的guava版本需在16.0以下版本,具体原因请看guava包中StopWatch的改变),因此HBase中就是因为版本太高而报错。如果改变guava版本使用16.0版本那么ES的javaAPI就会因为guava的版本太低而报错。怎么办呢?再次困扰我好久。
  于是乎查询了一下资料,发现在ES的官网上有一篇关于jar包冲突的blog。所以参考修改了一下,折腾一天终于搞定。这里提供两种解决方案:
方案一:
1、造成我出现上述的原因是由于我采用了ES较为常规的连接请求方式,如下:

Settings settings = Settings.settingsBuilder().put("cluster.name", "rube-es").put("client.transport.sniff", true).build();
TransportClient tClient = TransportClient.builder().settings(settings).build();
Client client = null;
String host = "";
client = tClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), 9300));

SearchResponse searchResponse = client.prepareSearch()
                    .setSearchType(SearchType.DEFAULT)
                    .setScroll(new TimeValue(60000))
                    .setIndices("indices")
                    .setTypes("type")
                    .setQuery(QueryBuilders.matchAllQuery())
                    .setFrom(0)
                    .setSize(500)
                    .execute()
                    .actionGet();

  因此造成以上问题,这里我们可以绕过此种方法去进行ES的请求,采用如下Http请求的方法:

AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
builder.setCompressionEnabled(true).setAllowPoolingConnection(true);
builder.setRequestTimeoutInMs((int) TimeUnit.MINUTES.toMillis(1));
builder.setIdleConnectionTimeoutInMs((int) TimeUnit.MINUTES.toMillis(1));

AsyncHttpClient client = new AsyncHttpClient(builder.build());
ListenableFuture future = client.preparePost(url).addHeader("content-type", "application/json").setBody(queryStr.getBytes("UTF-8")).execute();

  这样就绕过了guava版本的问题,可以修改项目中的guava版本为16.0以下,暂且解决这个问题,但是如果绕不过去怎么办,请看下面的方案二。

方案二:
1、首先是参考es官网blog:https://www.elastic.co/blog/to-shade-or-not-to-shade ,新建一个maven项目进行如下配置:


<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.0modelVersion>

    <groupId>my.elasticsearchgroupId>
    <artifactId>es-shadedartifactId>
    <version>1.0-SNAPSHOTversion>

    <properties>
        <elasticsearch.version>2.2.0elasticsearch.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.elasticsearchgroupId>
            <artifactId>elasticsearchartifactId>
            <version>${elasticsearch.version}version>
        dependency>
        <dependency>
            <groupId>org.elasticsearch.plugingroupId>
            <artifactId>shieldartifactId>
            <version>${elasticsearch.version}version>
        dependency>
    dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-shade-pluginartifactId>
                <version>2.4.1version>
                <configuration>
                    <createDependencyReducedPom>falsecreateDependencyReducedPom>
                configuration>
                <executions>
                    <execution>
                        <phase>packagephase>
                        <goals>
                            <goal>shadegoal>
                        goals>
                        <configuration>
                            <relocations>
                                <relocation>
                                    <pattern>com.google.guavapattern>
                                    <shadedPattern>my.elasticsearch.guavashadedPattern>
                                relocation>
                                <relocation>
                                    <pattern>org.jodapattern>
                                    <shadedPattern>my.elasticsearch.jodashadedPattern>
                                relocation>
                                <relocation>
                                    <pattern>com.google.commonpattern>
                                    <shadedPattern>my.elasticsearch.commonshadedPattern>
                                relocation>
                            relocations>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
                            transformers>
                        configuration>
                    execution>
                executions>
            plugin>
        plugins>
    build>

    <repositories>
        <repository>
            <id>elasticsearch-releasesid>
            <url>http://maven.elasticsearch.org/releasesurl>
            <releases>
                <enabled>trueenabled>
                <updatePolicy>dailyupdatePolicy>
            releases>
            <snapshots>
                <enabled>falseenabled>
            snapshots>
        repository>
    repositories>
project>

  如上配置完成后,其实就是将org.joda等4个可能有冲突的jar包通过maven-shade-plugin插件迁移后重新打个jar包从而使得在引入这个jar包时能够使用该jar包自己的依赖而不是使用外部依赖。

2、然后install项目,看到build success的话表示打包成功,新的依赖包会在.m2文件的仓库中。下面回到原来的集成项目的pom文件中。引入该jar包: (注意这里需要排除掉ES 2.3.3的jar包,不然maven会将2.3.3的jar包打进去,造成冲突)

<dependency>
    <groupId>my.elasticsearchgroupId>
    <artifactId>es-shadedartifactId>
    <version>1.0-SNAPSHOTversion>
    <exclusions>
        <exclusion>
            <groupId>org.elasticsearchgroupId>
            <artifactId>elasticsearchartifactId>
        exclusion>
    exclusions>
dependency>

你可能感兴趣的:(ElasticSearch,大数据)