Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java JDBC - How to connect to Oracle using tnsnames.ora

Tags:

java

oracle

jdbc

tnsnames.ora file contains the Databases and the their description (host + port).

  • Is it possible to establish a connection relying on the file mentioned above? (Say by providing only the DB name):

  • In order to find this file, I have to know the default oracle home I need to check in the windows registry for HKEY_LOCAL_MACHINE\Software\Oracle and then to have all the KEY_XXX files and then check which one appears first on the %PATH%. Is there a way to automatically find this file on the client computer?

like image 755
Maroun Avatar asked Jan 07 '13 11:01

Maroun


People also ask

What is the JDBC URL for Oracle?

Connection URL: The connection URL for the oracle10G database is jdbc:oracle:thin:@localhost:1521:xe where jdbc is the API, oracle is the database, thin is the driver, localhost is the server name on which oracle is running, we may also use IP address, 1521 is the port number and XE is the Oracle service name.


2 Answers

I wasn't even aware that using tnsnames with the thin driver is possible, but apparently it was added somewhere in version 10:

http://docs.oracle.com/cd/B19306_01/java.102/b14355/urls.htm#BEIDIJCE

In particular:

Note:

When using TNSNames with the JDBC Thin driver, you must set the oracle.net.tns_admin property to the directory that contains your tnsnames.ora file.

java -Doracle.net.tns_admin=%ORACLE_HOME%\network\admin

As mentioned, I haven't checked if this actually works.

I don't think that the "find the actual network config directory" logic is available via some Oracle function. You'll have to do it manually as outlined in your question, or maybe rely on the TNS_ADMIN environment variable being present. In that case, the java invocation would be

java -Doracle.net.tns_admin=%TNS_ADMIN%
like image 158
Chris Avatar answered Sep 22 '22 17:09

Chris


Well, in some GUIs the TNS driver configuration is simply not implemented or not working (NetBeans for example :-) )

https://netbeans.org/bugzilla/show_bug.cgi?id=231526

There is simple workaround here. You can take the entry directly from the tnsnames.ora file and attach it to the jdbc driver string as following:

Example from using odbc7.jar (Oracle 12c JDBC driver for JDK 7) to connect to Oracle 11gR2 RAC cluster:

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL= TCP)(HOST=hostA)(PORT= 1522))(ADDRESS=(PROTOCOL=TCP)(HOST=hostB)(PORT=1521)))(SOURCE_ROUTE=yes)(CONNECT_DATA=(SERVICE_NAME=DatabaseService)))

Be aware of putting double :: characters in the end as host:port:service, if you will put :: in the end like this:

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL= TCP)(HOST=hostA)(PORT= 1522))(ADDRESS=(PROTOCOL=TCP)(HOST=hostB)(PORT=1521)))(SOURCE_ROUTE=yes)(CONNECT_DATA=(SERVICE_NAME=DatabaseService)))::

You will end up with "NL Exception was generated" exception.

Another approach is to configure following property: System.setProperty("oracle.net.tns_admin","C:/app/product/11.2.0/client_1/NETWORK/ADMIN");

Of course, instead of hardcoded value, you can for example set up environment variable in your operating system like ORACLE_TNS_ADMIN and then reference it:

System.setProperty("oracle.net.tns_admin",System.getenv("ORACLE_TNS_ADMIN"));

or pass it to java process via -D switch on linux:

-Doracle.net.tns_admin=$ORACLE_TNS_ADMIN

and windows:as

-Doracle.net.tns_admin=%ORACLE_TNS_ADMIN%

Once our application is aware of TNS config file, we can connect by reference service name in TNSNAMES.ora file as in this full example:

 // tell the driver where to look for the TNSNAMES.ORA file
System.setProperty(
          "oracle.net.tns_admin",
          "C:/app/product/11.2.0/client_1/NETWORK/ADMIN");

// ORCL is net service name from the TNSNAMES.ORA file
String dbURL = "jdbc:oracle:thin:@ORCL";

// load the driver
Class.forName("oracle.jdbc.OracleDriver");

Connection conn = null;
Statement stmt = null;

try {
  conn = DriverManager.getConnection(dbURL,
                                     "your_username",
                                     "your_password");

  stmt = conn.createStatement();

  ResultSet rs = stmt.executeQuery("SELECT dummy FROM dual");
like image 25
kensai Avatar answered Sep 21 '22 17:09

kensai