spark集成es遇到Guava jar包冲突问题:java.lang.NoSuchMethodError
错误信息:
Caused by: java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecutor()Ljava/util/concurrent/Executor;
at org.elasticsearch.threadpool.ThreadPool.<clinit>(ThreadPool.java:190)
at org.elasticsearch.client.transport.TransportClient$Builder.build(TransportClient.java:133)
at org.springframework.data.elasticsearch.client.TransportClientFactoryBean.buildClient(TransportClientFactoryBean.java:89)
at org.springframework.data.elasticsearch.client.TransportClientFactoryBean.afterPropertiesSet(TransportClientFactoryBean.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 56 more
通过前三行错误信息可以看到是找不到某个方法,这种问题一种可能性是缺失jar包,一种可能性是jar包冲突,我这里是jar包冲突。
解決过程
根据报错信息找到相关jar,可以看出是guava的jar冲突
于是开始排除guava
在intellij idea的Maven projects 中搜索和Guava相关jar,如下图
可以看到项目有很多地方依赖guava,选择一个后回车,可以看到这个guava的版本,双击后还可以进入当前jar所在的pom文件。如果想排除这个jar,就如下操作
这样pom文件也会同步修改,如此步骤依次排除,直到最后剩下自己满意的。
我排除之后。将项目打包,上传到spark集群.然后执行。很郁闷,还是同样的问题。
明明我的Guava jar中是有这个方法的,但为何老是找不到呢。在经过一段时间思考后还是没有发现问题的原因,于是找到同事一起讨论这个问题,后来发现,spark容器也依赖了Guava, 而其依赖的版本是1.4 。而es 中 依赖的Guava 是1.8 ,在1.8的jar中是有那个方法的,但1.4中却是没有的,这也就解释了为何在项目中把Guava该排的都排除了却依然有问题。于是将spark集群中的Guava jar替换掉,重新执行项目,可以正常执行。
问题总结:
1, 解决问题时,考虑问题不够全面
在排除项目中可能的冲突jar后,依然有这个问题,就应该把思维发散出去,考虑一下其它有可能导致jar冲突的可能性。
2,解决问题时如果没有思路,就从头到尾梳理项目运行的整个流程,每个细节都不要忽略,你会发现,往往是一些你没有注意到的地方导致的问题的发生,而我们却把精力放在了别处,方向错了,终点遥不可期。
3, 如何让spark引用项目中指定的jar,这将是我们接下来需要解决的问题,由于刚刚接触spark,这块需要去分析下。
问题延伸:
如下错误可能是jar包冲突:
1.java.lang.NoSuchMethodError
2.java.lang.ClassNotFoundException
3.java.lang.NoClassDefFoundError
Jar 冲突排除方法:
1, 通过intellij idea 去排除,方法同上
2, 通过maven命令查看依赖信息,手动排除,例如
mvn dependency:tree | grep guava
还没有评论,来说两句吧...