У меня есть приложение, которое пытается подключиться к Impala и Oracle. Ниже определены 2 bean-компонента.
Драйвер Impala — ImpalaJDBC41-2.5.41.jar Драйвер Oracle — ojdbc6.jar
<bean id = "ID1" class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "com.cloudera.impala.jdbc41.Driver"/>
<property name = "url" value = "jdbc:impala://impalahost:21050/;AuthMech=1;KrbRealm=myrealm;KrbServicName=impala;KrbHostFQDN=xxx" />
</bean>
<bean id = "ID2" class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "oracle.jdbc.driver.OracleDriver"/>
<property name = "url" value = "jdbc:oracle:thin:@//oraclehost:1523/DB" />
<property name = "username" value = "myuser" />
<property name = "password" value = "pwd" />
<property name = "connectionProperties">
<props>
<prop key = "defaultRowPrefetch">5000</prop>
</props>
</property>
</bean>
При получении соединения "Oracle" со ссылкой на bean-компонент - ID2, получение этого исключения (на удивление, оно переходит в код драйвера cloudera) -
==java.lang.NullPointerException
===Stack trace...
java.util.Hashtable.put(Unknown Source)
com.cloudera.jdbc.common.AbstractDriver.copyProperties(Unknown Source)
com.cloudera.jdbc.common.AbstractDriver.connect(Unknown Source)
java.sql.DriverManager.getConnection(Unknown Source)
java.sql.DriverManager.getConnection(Unknown Source) org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFrom
DriverManager(DriverManagerDataSource.java:173) org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFrom
Driver(DriverManagerDataSource.java:164) org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:149) org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119) org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
Те же конфигурации отлично работают с Java 1.7.
Я попытался использовать более новую версию для обоих драйверов; это не помогает.
Затем вы должны сообщить об ошибке в Impala.
Удивительно, но он отлично работает с Java 1.7 с такими же настройками. Если вы проверите исключение; даже если приложение пытается подключиться к Oracle, поток кода входит в драйвер impala и там не работает. Я попытался переименовать банку impala в ZImpalaJDBC41-2.5.41.jar, и все работает нормально. Драйвер Oracle загружается перед Impala. Это похоже на ошибку в том, как Java 1.8 обрабатывает оба драйвера.
Учитывая, что это исключение нулевого указателя внутри Impala, я был бы удивлен, если бы это была ошибка в DriverManager. Диспетчер драйверов будет опрашивать каждый драйвер, если он может подключиться с использованием предоставленного URL-адреса JDBC, если нет, он должен вернуть null (если URL-адрес не для драйвера) или выдать SQLException (если URL-адрес для драйвера, но что-то синтаксически неправильно, или соединение не может быть установлено). Похоже, что Impala не проверяет, может ли она использовать URL-адрес, а затем переходит к обработке URL-адреса, который затем терпит неудачу, потому что это не URL-адрес для Impala.
В любом случае, я заметил, что в вашем определении Oracle есть свойство без значения (<property name = "connectionProperties">), посмотрите, что произойдет, если вы удалите его или присвоите ему явное значение (например, value = ""). Учитывая, что это происходит в чем-то под названием copyProperties, мне интересно, может ли это быть проблемой с тем фактом, что Hashtable.put не допускает значения null.
Проблема возникает, когда драйвер Impala загружается до загрузки драйвера Oracle; поскольку ImpalaJDBC41-2.5.41.jar упоминается перед ojdbc6.jar (в алфавитном порядке). Итак, у меня было 2 варианта загрузки драйвера Oracle, и оба они работали нормально:
переименуйте банку Impala в ZImpala, чтобы она упоминалась после банки ojdbc
Но «более чистый и лучший» подход состоял в том, чтобы загрузить драйвер Oracle с пользовательским модулем, настроив его как источник данных JDBC внутри Jboss standalone.xml; который загрузит драйвер Oracle еще до того, как наше приложение EAR будет развернуто.
Это не связано с вашей проблемой (или я был бы удивлен, если бы это было так), но если вы используете Java 8, почему вы используете ojdbc6 (для Java 6)? В любом случае
java.sql.DriverManagerбудет перебирать все драйверы, чтобы увидеть, какой из них подключится. По-видимому, драйвер Impala проверяется перед драйвером Oracle. Это похоже на ошибку в драйвере Impala. Проверьте, доступна ли более новая версия, которая исправляет это.