似乎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
格式的确切问题是什么? (我只是删除所有空格来解决它)
答案 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文件,以查看是否可以通过这种方式纠正问题。