java.lang.ArrayIndexOutOfBoundsException при создании соединения с базой данных Oracle - PullRequest
6 голосов
/ 05 мая 2011

Похоже, что у Java-клиента Oracle есть ошибка - если файл tnsnames.ora содержит неуместные пробелы / табуляции / новые строки в определенных местах, вы получите исключение со следующей трассировкой:

java.lang.ArrayIndexOutOfBoundsException: <some number>
        at oracle.net.nl.NVTokens.parseTokens(Unknown Source)
        at oracle.net.nl.NVFactory.createNVPair(Unknown Source)
        at oracle.net.nl.NLParamParser.addNLPListElement(Unknown Source)
        at oracle.net.nl.NLParamParser.initializeNlpa(Unknown Source)
        at oracle.net.nl.NLParamParser.<init>(Unknown Source)
        at oracle.net.resolver.TNSNamesNamingAdapter.loadFile(Unknown Source)
        at oracle.net.resolver.TNSNamesNamingAdapter.checkAndReload(Unknown Source)
        at oracle.net.resolver.TNSNamesNamingAdapter.resolve(Unknown Source)
        at oracle.net.resolver.NameResolver.resolveName(Unknown Source)
        at oracle.net.resolver.AddrResolution.resolveAndExecute(Unknown Source)
        at oracle.net.ns.NSProtocol.establishConnection(Unknown Source)
        at oracle.net.ns.NSProtocol.connect(Unknown Source)
        at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1037)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:282)
        at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:468)
        at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:839)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:185)

Если вы берете приложение C ++ и пытаетесь подключиться к нему к базе данных с тем же tnsnames.ora в использовании - оно работает нормально. То же самое касается sqlplus. Также tnsping, который должен анализировать этот файл, не имеет проблем с разрешением имени службы. Похоже, Oracle слишком ленив, чтобы .trim() значения или что-то еще - и это та же проблема с клиентскими версиями Oracle 9, 10 и 11.

Есть идеи, почему существует эта проблема и какова точная проблема с форматом tnsnames.ora? (Я просто удаляю все пробелы, чтобы решить эту проблему)

Ответы [ 2 ]

4 голосов
/ 08 мая 2011

Я попробовал совет от GriffeyDog, но, к сожалению, он не решил проблему - так что в итоге я тоже check for your self approach:

Документация Oracle гласит, что структура записи в файле tnsnames.ora должна быть такой:

net_service_name= 
 (DESCRIPTION=
   (ADDRESS=...)
   (ADDRESS=...)
   (CONNECT_DATA=
    (SERVICE_NAME=sales.us.example.com)))

Наше было:

net_service_name= 
(DESCRIPTION=
(ADDRESS=...)
(ADDRESS=...)
(CONNECT_DATA=
(SERVICE_NAME=sales.us.example.com)))

Очевидно, что отступ имеет решающее значение - если любая из строк в блоке одного net_service_name начинается с индекса 1 - это исключение выдается.

Только после добавления отступа для всех (может быть пробел или табуляция) - это работает. Это не должно выглядеть хорошо, но должно иметь какое-то смещение.

Важное замечание - единственная проблема с '(', правила отступа не применяются к ')'.
Например. приведенный ниже пример отлично подходит:

net_service_name= 
     (DESCRIPTION=
       (ADDRESS=...
)
       (ADDRESS=...
)
       (CONNECT_DATA=
        (SERVICE_NAME=sales.us.example.com))
)

После поиска этой проблемы, которая будет задокументирована - я наконец-то обнаружил, что она действительно задокументирована в http://download.oracle.com/docs/cd/A57673_01/DOC/net/doc/NWUS233/apb.htm

А вот важный отрывок:

Даже если вы не решите сделать отступ для ваших файлов таким образом, вы должны сделать отступ в обернутой строке хотя бы на один пробел, или будет неверно истолкован как новый параметр . Допустим следующий формат:

(ADDRESS = (СООБЩЕСТВО = tcpcom.world) (ПРОТОКОЛ = TCP)
(HOST = max.world) (PORT = 1521)) * * тысяча тридцать-три

Следующая раскладка недопустима:

(ADDRESS = (СООБЩЕСТВО = tcpcom.world) (ПРОТОКОЛ = TCP)
(HOST = max.world) (PORT = 1521))

2 голосов
/ 05 мая 2011

Я видел аналогичные проблемы, возникающие при сохранении текстового файла в конце строки в стиле Unix (LF) по сравнению с DOS / Windows-стиле (CR / LF) или наоборот. Вы можете попробовать открыть файл tnsnames.ora в редакторе, который поддерживает сохранение в обоих форматах, чтобы посмотреть, сможете ли вы решить проблему таким образом.

...