我正在Cloudera Hive和Spark 5.10.2上构建项目。
当我尝试使用Thrift客户端发送请求时,出现以下错误:
ERROR HiveConnection: Error opening session
org.apache.thrift.TApplicationException: Required field 'client_protocol' is unset! Struct:TOpenSessionReq(client_protocol:null, configuration:{use:database=default})
at org.apache.thrift.TApplicationException.read(TApplicationException.java:111)
at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:79)
at org.apache.hive.service.cli.thrift.TCLIService$Client.recv_OpenSession(TCLIService.java:156)
at org.apache.hive.service.cli.thrift.TCLIService$Client.OpenSession(TCLIService.java:143)
at org.apache.hive.jdbc.HiveConnection.openSession(HiveConnection.java:583)
at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:192)
at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
深入研究项目的依赖关系树,我发现问题是由Cloudera的hive-exec中肮脏的猴子补丁引起的,在其中定义了以下依赖关系:
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>${libthrift.version}</version>
</dependency>
但是节俭代码生成也用于生成libthrift的另一套实现,最终导致两个实现都存在于类路径中,并且其中一个实现是随机加载的。
我正在寻找适用于maven,gradle或sbt的插件,以便在两者同时存在时始终加载libthrift的生成版本,并且仅在没有其他选择的情况下才加载静态版本,即在hive-exec中声明包比libthrift中的软件包更高的优先级。是否有可能在整个Java生态系统中这样做?
非常感谢您的任何想法!
最佳答案
您尝试过maven dependency exclusion吗?
处理依赖项时,一些有用的东西:mvn help:effective-pom
和mvn dependency:tree
。