6

Oracle 的 java 客户端似乎有一个错误 - 如果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格式的确切问题是什么吗?(我只是删除所有空格来解决它)

4

2 回答 2

5

我尝试了 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

这是重要的摘录:

即使您不选择以这种方式缩进文件,您也必须将换行的行缩进至少一个空格,否则会被误读为新参数。以下布局是可以接受的:

(地址=(社区=tcpcom.world)(协议=tcp)
   (主机=max.world)(端口=1521))

不接受以下布局:

(地址=(社区=tcpcom.world)(协议=tcp)
(主机=max.world)(端口=1521))

于 2011-05-08T05:32:14.137 回答
2

当文本文件使用 Unix 样式的行尾 (LF) 与 DOS/Windows 样式 (CR/LF) 保存时,我已经看到类似的问题,反之亦然。您可以尝试使用支持两种格式保存的编辑器打开您的 tnsnames.ora 文件,看看您是否可以通过这种方式纠正问题。

于 2011-05-05T18:45:41.057 回答