如何在没有 ClassNotFound 异常的情况下在 Apache Tomcat 中配置 Impala/Hive2 JDBC 驱动程序
Posted
技术标签:
【中文标题】如何在没有 ClassNotFound 异常的情况下在 Apache Tomcat 中配置 Impala/Hive2 JDBC 驱动程序【英文标题】:How to configure Impala/Hive2 JDBC driver in Apache Tomcat without ClassNotFound exceptions 【发布时间】:2014-08-14 21:06:57 【问题描述】:我正在尝试将 Impala/Hive2 JDBC 驱动程序添加到使用 Tomcat 7 (7.0.54) 部署的现有应用程序中。其他 JDBC 驱动程序工作正常(Oracle、MS SS、SyBase)。
但是,驱动程序从未连接,并且总是抛出不会被 Eclipse (Kepler) 中的 Java (JDK 1.7.0_55) 捕获的异常。这是在 Windows 8.1 Lenovo T500 笔记本电脑上完成的。没有有意义的错误消息或堆栈跟踪。
为了找出错误发生的位置,我获取了 Hive 源代码并制作了一个简单的 Java 程序来测试在 DEBUG 中单步执行的 JDBC 连接。缺少的类在 jar 中的引用错误比在 Clouder's documentation 中指定的要少。 HiveConnection.java (org.apache.hive.jdbc) 中有错误:
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.http.impl.client.DefaultHttpClient;
我追踪了这些类存在的位置,并将以下 jar 添加到我制作的 UserLibrary 中:
hive-exec-0.12.0.jar which contains the packages for ....hive.ql.....
httpclient-4.2.5.jar which contains the packages for ....http.impl.client....
添加httpclient
后,仍然出现引用错误
httpClient.addRequestInterceptor - message = The type org.apache.http.HttpRequestInterceptor cannot be resolved. It is indirectly referenced from required .class files
我将此追踪到:httpcore-4.2.4.jar
独立 Java 程序成功连接到 Impala 守护程序。我将这些 jar 与 JDBC 包一起作为 Java 源代码添加到 Tomcat /WEB-INF/ib/ 文件夹中。 Tomcat 遇到了一些问题,包括无法发布 IndexOutOfBounds 异常。我发现这主要是由于hadoop-common
jar。我能够通过彻底清理 Tomcat 定义和项目并将这个 jar 添加为最后一个来发布它。还是试了几次。
然后,运行应用程序也停止,但在 DriverManager.getConnection(connstr) 处出现异常。这些错误总是与没有看到加载到 /WEB-INF/lib/ 文件夹中的 jar 文件中的各种类有关。删除然后重新导入它们按以下顺序遍历这些错误:
org/apache/http/client/httpclient (in httpclient jar)
org/apache/http/httprequestinterceptor (in httpcore jar)
org/apache/hadoop/conf/configuration (in hadoop-common jar)
org/apache/hadoop/hive/conf/hiveconf (in hive-common AND hive-exec jars)
HIVE_CLI_SERVICE_PROTOCOL_V6
的最后一个奇怪错误。后者很难追踪,直到我在 HiveConnection.java 的 Java 代码中看到它,其中 HIVE_CLI_SERVICE_PROTOCOL_Vx
被添加到支持的协议集合中。这用于检查来自 Impala 的响应,如果 Impala 使用不在列表中的响应,则连接被取消。在我拥有的版本中,使用了 V1-V3。我发现 SVN 上的最新源代码是 V7,但这些在 CDH5 附带的 JDBC 代码中没有使用。
执行另一个循环,删除所有内容,然后将库 jars 和 JDBC 源代码(所以没有添加 JDBC jar)添加到我的 Tomcat Java/src 文件夹中的包中:
org.apache.hadoop.hive.jdbc (Hive 1 driver)
org.apache.hive.jdbc (Hive 2 driver)
终于,我能够在 DEBUG 中单步调试 HiveConnection 并成功进行通信,并且可以检查来自 Impala 的响应。它响应它正在使用____V1 协议,因此它被接受了。
由于文档声明只需要一些 jar,但我发现需要更多的 jar 来满足导入语句,我如何配置 Tomcat 以便仅使用分布式 JDBC 驱动程序及其支持 jar?我怀疑Tomcat如何进行类加载可能存在问题,因为我注意到Catalina.jar及其类加载器中发生了杀手级异常(没有源代码,所以我不知道确切的位置或原因)。
【问题讨论】:
【参考方案1】:我能够从 Tomcat 连接到 Impala(尽管我使用的是 Tomcat 8,而不是 7)。 我将所有这些 jar 复制到 tomcats lib 目录:
commons-logging-1.1.3.jar
hive-metastore-0.12.0-cdh5.0.2.jar
libfb303-0.9.0.jar
slf4j-log4j12.jar
hadoop-common-2.3.0-cdh5.0.2.jar
hive-service-0.12.0-cdh5.0.2.jar
libthrift-0.9.0.cloudera.2.jar
hive-common-0.12.0-cdh5.0.2.jar
httpclient-4.2.5.jar
log4j-1.2.16.jar
hive-jdbc-0.12.0-cdh5.0.2.jar
httpcore-4.2.5.jar
slf4j-api-1.7.5.jar
【讨论】:
感谢您的评论。我刚刚做了一个关于 Cloudera 的数据科学分布的网络广播 (TechLab)。我注意到的一件事是另一个未记录的库依赖问题,即为 HDFS 和 YARN 操作编写自定义 Java。给那些认为这只是使用 Maven 的问题的人的快速消息:它不是。拥有未记录的库依赖项是不行的。在这种情况下,奇怪的解决方案是引用整个 hadoop lib jar 文件夹。有效。我没有时间穿过雷区。以上是关于如何在没有 ClassNotFound 异常的情况下在 Apache Tomcat 中配置 Impala/Hive2 JDBC 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章
尝试使用 DataflowRunner 时出现 ClassNotFound 异常
Apache Oozie 在创建 mysql DB 时抛出 classnotfound 异常
从 apache Spark 运行 java 程序时出现 ClassNotFound 异常
Faces Servlet - ClassNotFound 异常 [重复]