创建与Oracle数据库的连接时出现java.lang.ArrayIndexOutOfBoundsException

Ron*_*onK 6 java oracle tnsnames

看来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)
Run Code Online (Sandbox Code Playgroud)

如果您使用C++应用程序并尝试tnsnames.ora使用相同的方式将其连接到数据库- 它可以正常工作.同样如此sqlplus.还tnsping应该分析此文件没有问题,解决任何服务名称.似乎Oracle .trim()对于价值观或其他东西太懒了 - 而且Oracle客户端版本9,10和11也存在同样的问题.

知道为什么这个问题存在以及tnsnames.ora格式的确切问题是什么?(我只是删除所有空格来解决它)

Ron*_*onK 6

我尝试了 GriffeyDog 的建议,但不幸的是它没有解决问题 - 所以最终我也解决了check for your self approach:

Oracle的文档指出文件中记录的结构tnsnames.ora应该是这样的:

net_service_name= 
 (DESCRIPTION=
   (ADDRESS=...)
   (ADDRESS=...)
   (CONNECT_DATA=
    (SERVICE_NAME=sales.us.example.com)))
Run Code Online (Sandbox Code Playgroud)

我们的是:

net_service_name= 
(DESCRIPTION=
(ADDRESS=...)
(ADDRESS=...)
(CONNECT_DATA=
(SERVICE_NAME=sales.us.example.com)))
Run Code Online (Sandbox Code Playgroud)

显然,缩进至关重要 - 如果单个块中的任何行net_service_name从索引 1 开始 - 就会抛出此异常。

只有当你为所有内容添加缩进(可以是空格或制表符)时 - 它才有效。它不必看起来很好,但必须有某种偏移。

重要提示 - 唯一的问题是'(',缩进规则不适用于')'。
例如下面的例子就完全没问题:

net_service_name= 
     (DESCRIPTION=
       (ADDRESS=...
)
       (ADDRESS=...
)
       (CONNECT_DATA=
        (SERVICE_NAME=sales.us.example.com))
)
Run Code Online (Sandbox Code Playgroud)

在搜索要记录的此问题后 - 我终于发现它确实记录在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))