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

时间:2011-05-05 17:58:53

标签: 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)

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

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

2 个答案:

答案 0 :(得分:4)

我尝试了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)(PROTOCOL = TCP)
  (HOST = max.world)(PORT = 1521))

     

以下布局不可接受:

     

(ADDRESS =(社区= tcpcom.world)(PROTOCOL = TCP)
  (HOST = max.world)(PORT = 1521))

答案 1 :(得分:2)

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