1、场景描述
因业务场景需要连接hive及ES,所以项目中需要整合这两项,那么在整合中遇到了jar包冲突的问题,项目是用的是Maven工程,hive 是用的CDH中的。
2、pom文件 中引用的hive及ES如下
<!-- hadoop 2.6.0 && cdh 5.13.3 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-hadoop</artifactId>
<version>2.5.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0-cdh5.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>2.6.0-mr1-cdh5.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>1.1.0-cdh5.13.3</version>
</dependency>
<!-- es6.3.0 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.3.0</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
<version>2.8.3</version>
</dependency>
3、测试一把吧
因为项目有使用spring,那么连接hive 使用的是JdbcTemplate, Junit测试代码如下:
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 获取某个库下的所有表
* ps:
* testdb 库
*
*/
@Test
public void queryTables(){
List<Map<String, Object>> queryForList = jdbcTemplate.queryForList("SHOW TABLES IN testdb ");
System.out.println(queryForList);
}
运行后:
Caused by: java.lang.NoSuchMethodError: io.netty.util.AttributeKey.newInstance(Ljava/lang/String;)Lio/netty/util/AttributeKey;
at org.elasticsearch.transport.netty4.Netty4Transport.<clinit>(Netty4Transport.java:232)
at org.elasticsearch.transport.Netty4Plugin.getSettings(Netty4Plugin.java:56)
at org.elasticsearch.plugins.PluginsService.lambda$getPluginSettings$0(PluginsService.java:89)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.elasticsearch.plugins.PluginsService.getPluginSettings(PluginsService.java:89)
at org.elasticsearch.client.transport.TransportClient.buildTemplate(TransportClient.java:144)
at org.elasticsearch.client.transport.TransportClient.<init>(TransportClient.java:280)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:128)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:114)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:104)
at com.perfect.lkt.dao.impl.ElasticSearchConnection.<init>(ElasticSearchConnection.java:35)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 44 more
呦呵…mmp呀,所谓没事不惹事,来事不怕事的原则,分析吧
4、错误分析
首先看错误类型是,找不到这个方法,难道是缺少netty的jar包?先去确认下依赖的netty jar 有没有下载下来或引用到吧。去maven 工程下的 maven Dependencies 目录下看下, 结果发现有多个版本的netty 包,发生了冲突,如下图:
我们都知道maven 引用jar时,它会把依赖的jar自动引进来,省去我们不少麻烦,但也会很容引起jar包冲突
5、bug解决
既然是jar包冲突的问题,就把冲突的jar 删除,保留一个就好,按照高版本兼容低版本的原则,我们保留高版本的。
那么怎么删除呢,那俩低版本的netty jar 到底是谁的依赖加载进来的呢,是hive 还是ES? 所以我们要先确定 这俩低版本的netty jar 是谁的依赖。
可使用maven的 mvn dependency:tree
命令查看下,他会生成一个jar 依赖的树层机构,执行这个命令有两点要素:
1) 你的maven 的环境变量已经配置了
2)你要到你工程的pom文件的目录下执行
执行成功后如下:
最顶级的那个jar ,就是你在pom 中的引用,看来在spring-data-hadoop
引用中禁掉netty就OK了,可以使用exclusions
标签,如下:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-hadoop</artifactId>
<version>2.5.0.RELEASE</version>
<!-- 因与es中的netty jar冲突,所以这里排除依赖 -->
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
</exclusions>
</dependency>
再次运行测试,已完美解决,能够同时兼容hive和ES了。