java.lang.arrayindexoutofboundsexception quando si crea una connessione a un database Oracle
Domanda
Sembra che il client Java di Oracle abbia un bug - se il tnsnames.ora
Il file ha spazi/schede/nuove linee fuori posto in luoghi particolari, ottieni un'eccezione con la seguente traccia:
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)
Se prendi un'applicazione C ++ e provi a connetterti al database con lo stesso tnsnames.ora
In uso: funziona bene. Lo stesso vale per sqlplus
. Anche tnsping
Il che dovrebbe analizzare questo file non ha problemi a risolvere alcun nome di servizio. Sembra che Oracle fosse troppo pigro per .trim()
I valori o qualcosa del genere - ed è lo stesso problema con le versioni del client Oracle 9, 10 e 11.
Qualsiasi idea del perché esiste questo problema e qual è il problema esatto con il tnsnames.ora
formato? (Rimuovo solo tutti gli spazi bianchi per risolverlo)
Soluzione
Ho provato il consiglio da Griffeydog ma sfortunatamente non ha risolto il problema - quindi alla fine anche io il check for your self approach
:
La documentazione di Oracle afferma che la struttura di un record nel tnsnames.ora
Il file dovrebbe essere come tale:
net_service_name=
(DESCRIPTION=
(ADDRESS=...)
(ADDRESS=...)
(CONNECT_DATA=
(SERVICE_NAME=sales.us.example.com)))
Il nostro era:
net_service_name=
(DESCRIPTION=
(ADDRESS=...)
(ADDRESS=...)
(CONNECT_DATA=
(SERVICE_NAME=sales.us.example.com)))
Apparentemente il rientro è cruciale - se una qualsiasi delle linee nel blocco di un singolo net_service_name
Inizia da Index 1 - questa eccezione viene lanciata.
Solo una volta aggiunta il rientro a tutti (può essere spazi o schede): funziona. Non deve avere un bell'aspetto, ma deve avere un offset di qualche tipo.
Nota importante: l'unico problema è con '('
, le regole di rientro non si applicano a ')'
.
Ad esempio, l'esempio seguente va benissimo:
net_service_name=
(DESCRIPTION=
(ADDRESS=...
)
(ADDRESS=...
)
(CONNECT_DATA=
(SERVICE_NAME=sales.us.example.com))
)
Dopo aver cercato questo problema da documentare, ho finalmente scoperto che in effetti è documentato a http://download.oracle.com/docs/cd/a57673_01/doc/net/doc/nwus233/apb.htm
Ed ecco l'importante estratto:
Anche se non scegli di rientrare i tuoi file in questo modo, devi rientrare in una linea avvolta da almeno uno spazio o Sarà e male come un nuovo parametro. Il seguente layout è accettabile:
(Indirizzo = (community = tcpcom.World) (protocollo = TCP)
(Host = max.world) (porta = 1521))Il seguente layout non è accettabile:
(Indirizzo = (community = tcpcom.World) (protocollo = TCP)
(Host = max.world) (porta = 1521))
Altri suggerimenti
Ho visto problemi simili quando un file di testo viene salvato con End-of Lines (LF) in stile UNIX contro DOS/Windows in stile (CR/LF) o viceversa. Potresti provare ad aprire il tuo file tnsnames.ora con un editor che supporta il salvataggio in entrambi i formati per vedere se puoi correggere il problema in quel modo.