PROBLEM |
You are attempting to connect to an Oracle instance using JDBC
and you are receiving the following error.
|
Bugzero is proven
Go for it!
|
java.sql.SQLException: Io exception:
The Network Adapter could not establish connection
SQLException: SQLState (null) vendor code (17002)
|
Any or all of the following conditions may also apply:
1) You are able to establish a SQL*Plus connection from the same
client to the same Oracle instance.
2) You are able to establish a JDBC OCI connection, but not a Thin
connection from the same client to the same Oracle instance.
3) The same JDBC application is able to connect from a different
client to the same Oracle instance.
4) The same behavior applies whether the initial JDBC connection
string specifies a hostname or an IP address.
|
|
REDISCOVERY
|
To verify whether you are hitting this problem, verify whether the
Oracle instance is configured for Multithreaded Server (MTS).
If the Oracle instance is not configured for MTS, you are probably
encountering a different problem. Otherwise, continue. Try
forcing the JDBC connection to use a dedicated server instead
of a shared server. This can be accomplished in several ways.
For JDBC OCI or Thin, this can be done by reconfiguring the server
for dedicated connections only. This approach, however, may not be
feasible in many cases. In such cases, the following options apply:
For JDBC OCI:
|
1) Add the (SERVER=DEDICATED) property to the TNS connect string
stored in the tnsnames.ora file on the client.
2) Set the user_dedicated_server=ON in sqlnet.ora on the client.
For JDBC Thin:
You must specify a full name-value pair connect string (the same
as it might appear in the tnsnames.ora file) instead of the short
JDBC Thin syntax. For example, instead of
"jdbc:oracle:thin:@host:port:sid"
you would need to use a string of the form
"jdbc:oracle:thin:@(DESCRIPTION=" +
"(ADDRESS_LIST=" +
"(ADDRESS=(PROTOCOL=TCP)" +
"(HOST=host)" + =
"(PORT=port)" +
")" +
")" +
"(CONNECT_DATA=" +
"(SERVICE_NAME=sid)" +
"(SERVER=DEDICATED)" +
")" +
")"
|
If the connection works fine after having made these changes, it is
very likely that this is the problem you are encountering. In this
case, one last test will help to verify this fact.
Log into the remote host on which the Oracle instance is running and execute the
appropriate command to determine what the server 'thinks' its
hostname is (i.e. the name that was configured when the server was
installed and configured). For example, on a Unix host the
'hostname' command can be used for this purpose.
Using the name displayed (e.g. by the hostname command), exactly as it appeared
(i.e. if the output from the hostname command had the domain name
included, then include it), return to the client which was unable to
connect and try pinging the server.
NOTE: It is critical that you attempt to ping the server using
EXACTLY the same hostname you got from the server.
If you are unable to ping the server
via this hostname, then you almost certainly hitting this problem.
If not, this may be a new issue, but at least you will have found a
workaround (i.e. use a dedicated connection).
|
EXPLANATION
|
To understand why this problem occurs, one must
first understand the differences in how the listener handles
connections to shared servers versus dedicated servers.
When connecting to a dedicated server, the client connects to the
listener (via hostname or IP address). The listener then spawns a
dedicated server process and hands off the socket used to accept
the client connection to that server. The client and server then
start communicating via the endpoints established by the initial
connection. NOTE: There is only one connection in this case.
When connecting to a shared server, the initial client connection
to the listener is the same. However, with MTS, there is no need
to spawn a new server process; a pool of shared processes already
exists. Also, clients do not communicate directly with the server
processes in MTS; rather, they communicate with a dispatcher.
For this reason, when setting up an MTS connection, the listener
sends a redirect message back to the client asking the client to
close the connection to the listener and connect to a dispatcher.
The information in this message includes the hostname and a port
number for the appropriate dispatcher. The redirect message will
ALWAYS specify a hostname, even if the client initially provided
an IP address.
If, for any reason, the hostname provided to
the listener (e.g. by the 'hostname' or another command) doesn't
agree with the hostname by which the server is known on the client,
the connection fails.
On the other hand, if "(SERVER=DEDICATED)" already appears in the
TNS connect string in tnsnames.ora or if "use_dedicated_server=ON"
already appears in the sqlnet.ora file, you may find that SQL*Plus
and/or JDBC OCI work fine, while JDBC Thin fails.
|
SOLUTION
|
Obviously, one solution is to use dedicated servers. However, this
may not always be feasible.
The key is to make sure the hostname on both the client and server agree. This can be
accomplished by reconfiguring either the client or the server, but
there are things to be aware of in both cases.
If the server is configured to return a different hostname, then it is possible that
other clients which used to work will now fail.
In some cases, it may not be feasible to reconfigure the client. For example, if
the server version of the hostname does not include the domain, you
would need to remove the domain portion of the hostname on the
client; but, if the client needs to connect to more than one server
with the same base name in different domains, this may not be
possible, as the hostname may be ambiguous.
|
REFERENCES
|
bug# 1269734: java.sql.SQLException: Io exception: The Network Adapter could not be found.
|