Oracle 12c database connection using thin driver throws IO error - java

I'm following the JDBC Developer's Guide and trying to test the JDBC thin driver connection using a short java program.
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
class JDBCVersion
{
public static void main (String args[]) throws SQLException
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:hr/hr#localhost:1522:orcl");
Connection conn = ods.getConnection();
// Create Oracle DatabaseMetaData object
DatabaseMetaData meta = conn.getMetaData();
// gets driver info:
System.out.println("JDBC driver version is " + meta.getDriverVersion());
}
} //<host>:<port>:<service>
I've tried every possible <host>:<port>:<service> combination but still get a java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
I've successfully tested the OCI driver using another program included in the tutorial....but can't get this one to work. My application will be using the thin driver to connect to the database so my frustration level is....climbing.
Any help is appreciated.

Maybe following comments could explain why you need the sevice name instead of the SID in the URL.
the Oracle JDBC FAQ mention that SIDs will be cease to be supported in one of the next few releases of the database
the Oracle JDBC devolopers guide mention Always connect to a service. Never use instance_name or SID because these do not direct to known good instances and SID is deprecated
the Oracle 2 day + Java developer tutorial mention the syntax jdbc:oracle:driver_type:[username/password]#//host_name:port_number:SID which seems to be a mixture of SID and service name URL (following the other documents and your working example)
in contrast the javadoc for OracleDriver mention only the SID syntax
the Oracle FAQ wiki mention both syntax
.
jdbc:oracle:thin:[USER/PASSWORD]#[HOST][:PORT]:SID
jdbc:oracle:thin:[USER/PASSWORD]#//[HOST][:PORT]/SERVICE

I'm able to connect to my container DB (containing my tables, packages, etc.) using the username/password.
Returns:
JDBC driver version is 12.1.0.2.0
Still can't connect to the tutorial "HR" PDB that comes with the oracle 12c install and which the JDBC tutorial uses.
Edit:
Got it to work using the following:
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
class JDBCVersion
{
public static void main (String args[]) throws SQLException
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:#//localhost:1522/pdborcl.global.XXXXXXXX.com");
ods.setUser("hr");
ods.setPassword("hr");
Connection conn = ods.getConnection();
// Create Oracle DatabaseMetaData object
DatabaseMetaData meta = conn.getMetaData();
// gets driver info:
System.out.println("JDBC driver version is " + meta.getDriverVersion());
}
}
Still don't understand why I need the full global name instead of the instance name.

When connecting to a PDB you should always use the PDB's service name in the connection string. It looks like your PDB's service is "pdborcl.global.XXXXXXXX.com" so that's what you need to use to connect the PDB directly.
Personally I find it easier to use the long URL format:
"jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=pdborcl.global.XXXXXXXX.com)))"
It makes it obvious that you're using a Service name instead of an SID.
The beauty of it is that you can also easily test your connection string with sqlplus:
sqlplus "hr/hr#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=pdborcl.global.XXXXXXXX.com)))"
If sqlplus works there is not reason why the JDBC Thin driver wouldn't.
Finally you can also connect the root database using a privilege user and then execute "ALTER SESSION SET CONTAINER=pdb" to switch to the PDB. Should you decide to do so you would have to modify your connection string to connect to the root container first. It should have its own service name.

Related

Is there a way to set APPL_NAME on the DB2 Connection externally instead of "db2jcc_application" (e.g. with System Property)

I am using a Java application that connects to DB2 over JDBC. It creates the connection such that the application name (sysibmadm.applications -> APPL_NAME) remains the JDBC default "db2jcc_application". Is there a way to externally set the APPL_NAME to a desired value? (e.g. in Oracle, I can pass -Doracle.jdbc.v$session.program=MyApplName to have a similar effect).
I want to do this so that I can clearly identify all the connections coming into my DB2. Currently all the java applications show up as "db2jcc_application".
I wrote a small piece of code to illustrate this ...
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class DB2ApplName {
public static void main(String[] args) throws ClassNotFoundException, SQLException, InterruptedException {
Class.forName("com.ibm.db2.jcc.DB2Driver");
Properties connProps = new Properties();
connProps.put("user", "<my db2 user>");
connProps.put("password", "<my db2 password>");
// Create a connection **WITHOUT** Application Name
Connection connWithoutApplName = DriverManager.getConnection("jdbc:db2://<ip>:<port>/<dbname>",
connProps);
// Add Application Name to the properties
connProps.put("clientProgramName", "MyApplName");
// Create a connection **WITH** Application Name
Connection connWithApplName = DriverManager.getConnection("jdbc:db2://<ip>:<port>/<dbname>",
connProps);
System.out.println("Sleeping for 60 seconds - check the connections.");
Thread.sleep(60000L); // During this time I will run query on DB2 to see connection details.
connWithoutApplName.close();
connWithApplName.close();
}
}
This code creates two connections, one wihtout ApplName set and one with ApplName set.
When the code is in Thread.sleep, I query the db ...
select appl_name from sysibmadm.applications
where client_nname = '<my client ip>' with ur;
APPL_NAME
------------------
db2jcc_application
MyApplName
As you can see the second connection has the application name correctly stamped, but the first connection simply has "db2jcc_application" as its name. But, of course, I could do this only if I could modify the application code - which I cannot.
The second way I found I can do this is by setting the JDBC URL in the application settings/properties in a particular fashion. Instead of simply using JDBCURL=jdbc:db2://<ip>:<port>/<dbname> in the application settings, if I set JDBCURL=jdbc:db2://<ip>:<port>/<dbname>:clientProgramName=MyApplName;, then the application name gets stamped correctly. Unfortunately, for certain applications that we have, we need to start multiple JVM processes, but I cannot set the above mentioned setting separately for each of these processes. I can set JVM parameters (such as -D parameters) separately for each process.
Thus, I am looking to see if there is a way to externally pass the Application Name so that the JDBC Driver will pick it up and stamp it on the connection.
Below is the list of available properties, which can be set via a JVM parameter or a properties file:
IBM Data Server Driver for JDBC and SQLJ configuration properties.
According to this link, you are not able to set the clientProgramName property in such a way.

Get URL of Solid DataBase for JDBC

I have a Solid Database. And I want to connect to this DB by JDBC. How can I get URL for connection creation?
[EDIT]
For more information:
SOLID JDBC Driver
Programmer's Guide
SOLID JDBC Driver 2.3 Readme
Registering JDBC Driver
The JDBC driver manager, which is written entirely in Java, handles loading and unloading drivers and interfacing connection requests with the appropriate driver. It was JavaSoft's intention to make the use of a specific JDBC driver as transparent as possible to the programmer and user.
The driver can be registered with the three alternative ways, which are shown below. The parameter required by Class.forName and Properties.put functions is the name of the driver, which is solid.jdbc.SolidDriver.
// registration using Class.forName service
Driver)Class.forName("solid.jdbc.SolidDriver")
// a workaround to a bug in some JDK1.1 implementations
Driver d = (Driver)Class.forName("solid.jdbc.SolidDriver").newInstance();
// Registration using system properties variable also
Properties p = System.getProperties();
p.put("jdbc.drivers", "solid.jdbc.SolidDriver");
System.setProperties(p);
Connecting to the database
Once the driver is succesfully registered with the driver manager a connection is established by creating a Java Connection object with the following code. The parameter required by the DriverManager.getConnection function is the JDBC connection string.
Connection conn = null;
try {
conn = DriverManager.getConnection(sCon);
}
catch (Exception e) {
System.out.println("Connect failed : " + e.getMessage());
throw new Exception("Halted.");
}
The connect string structure is jdbc:solid://://. The string "jdbc:solid://fb9:1314/dba/dba" attempts to connect a SOLID Server in machine fb9 listening tcp/ip protocol at port 1314.
The application can establish several Connection objects to database. Connections can be closed be the following code.
conn.close();

problems in connecting java with ms access

hye all..
i am currently doing my final year project in java.i want to connect a ms access database using java.But sadly i'm using windows 7 starter that cannot support odbc.do you have any idea i can solve this problem?thank for all your coming idea and help =)
Simply try to have another OS get installed or try to have some of the drivers that support JDBC and you will surely able to work in connecting dtabase with java.
You could try JDBC drivers like these:
http://www.csv-jdbc.com/stels_mdb_jdbc.htm
http://www.hxtt.com/access.html
Both are commercial products.
A free option would be to migrate the database to SQL Server Express and then use the SQL Server JDBC drivers to connect to that.
I used the sun.jdbc.odbc.JdbcOdbcDriver to connect to a MS Access database. Have that in the same directory as the class file and it should work. Although it should come already installed in the Java SDK.
This is a sample of a practice program I made a while ago.
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
System.out.println("Driver loaded");
// Establish a connection
Connection connection = DriverManager.getConnection
("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=(MS ACCESS DATABASE DIRECTORY)");
System.out.println("Database connected");
// Create a statement
Statement statement = connection.createStatement();
// Execute a statement
ResultSet resultSet = statement.executeQuery
("select f_name, l_name from Test where f_name = 'Luke'"); // For example
// Iterate through the result and print the results
while (resultSet.next())
System.out.println(resultSet.getString(1) + "\t" + resultSet.getString(2) );

Help me connecting java and oracle

Can anybody explain me these classes and methods?
DriverManager.registerDriver
(new oracle.jdbc.driver.OracleDriver());
conn = java.sql.DriverManager.getConnection(
"jdb:ocracle:thin:username/password#machine.us.company.com:1234:dbSID");
Thanks
Let's decode the lines of your code block:
1. DriverManager.registerDriver
2. (new oracle.jdbc.driver.OracleDriver());
3. conn = java.sql.DriverManager.getConnection(
4. "jdbc:oracle:thin:username/password#machine.us.company.com:1234:dbSID");
Line 2:
Creates a new instance of oracle.jdbc.driver.OracleDriver, a JDBC Driver for the Oracle database. A JDBC driver implements the interfaces and classes defined by the JDBC API that programmers use to connect to a database and perform queries.
Line 1
Registers the instance of the oracle.jdbc.driver.OracleDriver to the DriverManager class which is the traditional management layer of JDBC, working between the user and the drivers. It handles establishing a connection between a database and the appropriate driver.
Line 3:
Now that the communication layer between the JDBC application and the database is ready, you can create a connection by calling getConnection() method of the DriverManager class.
Line 4:
This is the "connection string" or "database URL". This String identifies the database you want to connect to. The scheme of this URL is specific to the database provider and/or the driver (here, Oracle and its "thin" driver).
Note that prior to Java 6, calling Class.forName was the preferred way to load and register a JDBC Driver. It was the responsibility of the Driver to call DriverManager.registerDriver.
[...] All Driver classes should be written with a static section (a static initializer) that creates an instance of the class and then registers it with the DriverManager class when it is loaded. Thus, a user would not normally call DriverManager.registerDriver directly; it should be called automatically by a Driver class when it is loaded.
Check the Driver Manager chapter from the JDBC documentation for more details.
This is JDBC which is the way Java programs talk to a database, and your sample explicitly asks for the Oracle driver which requires their driver in your classpath.
Sun has a good tutorial on the matter at http://java.sun.com/docs/books/tutorial/jdbc/overview/index.html
The DriverManager class in java handles the connections between the database and the jdbc drivers, routing db i/o to the correct jdbc driver (you can have multiple drivers active ie connections to multiple types of database).
Drivers are registered with the DriverManager so that they become part of its working set. The next step is to create a connection to your database, so you can run queries. This is achived by the
Connection conn = DriverManager.getConnection("jdb:ocracle:thin:username/password#machine.us.company.com:1234:dbSID")
method. The connection String passed into the getConnection() method is driver-specific, you need to RTFM for each driver. Note that the DriverManager selects the driver automatically from its list of registered drivers, according to the syntax of the connection string you pass in.
The Connection object returned is your handle for preparing statements and running queries against the database

How can I use the MS JDBC driver with MS SQL Server 2008 Express?

My configuration:
windows XP SP3
JDBC 2005
MS SQL Server 2008 Express, exposed via tcp/ip on port 1433
sqljdbc.jar in class path
I tried:
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
con = DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433/SQLEXPRESS2008;databaseName=Test;selectMethod=cursor", "sa", "");
}
catch (Exception e) {
e.printStackTrace();
}
But it always throws an exception:
java.sql.SQLException: No suitable driver
I also tried the following urls:
localhost:1433/SQLEXPRESS2008
localhost/SQLEXPRESS2008
localhost
Same results.
Any help?
You have the wrong URL.
I don't know what you mean by "JDBC 2005". When I looked on the microsoft site, I found something called the Microsoft SQL Server JDBC Driver 2.0. You're going to want that one - it includes lots of fixes and some perf improvements. [edit: you're probably going to want the latest driver. As of March 2012, the latest JDBC driver from Microsoft is JDBC 4.0]
Check the release notes. For this driver, you want:
URL: jdbc:sqlserver://server:port;DatabaseName=dbname
Class name: com.microsoft.sqlserver.jdbc.SQLServerDriver
It seems you have the class name correct, but the URL wrong.
Microsoft changed the class name and the URL after its initial release of a JDBC driver. The URL you are using goes with the original JDBC driver from Microsoft, the one MS calls the "SQL Server 2000 version". But that driver uses a different classname.
For all subsequent drivers, the URL changed to the form I have here.
This is in the release notes for the JDBC driver.
Download the latest JDBC Driver (i.e. sqljdbc4.0) from Microsoft's web site
Write the program as follows:
import java.sql.*;
class testmssql
{
public static void main(String args[]) throws Exception
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con=DriverManager.getConnection("jdbc:sqlserver://localhost:1433;
databaseName=chapter16","sa","123");//repalce your databse name and user name
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("Select * from login");//replace your table name
while(rs.next())
{
String s1=rs.getString(1);
String s2=rs.getString(2);
System.out.println("UserID:"+s1+"Password:"+s2);
}
con.close();
}
}
Compile the program and set the jar classpath viz: set classpath=C:\jdbc\sqljdbc4.jar;.; If you have saved your jar file in C:\jdbc after downloading and extracting.
Run the program and make sure your TCP/IP service is enabled. If not enabled, then follow these steps:
Go to Start -> All Programs -> Microsoft SQL Server 2008 -> Configuration tools -> SQL Server Configuration Manager
Expand Sql Server Network Configuration: choose your MS SQL Server Instance viz. MSQSLSERVER and enable TCP/IP.
Restart your MS SQL Server Instance. This can be done also from the right click menu of Microsoft SQL Server Management Studio at the root level of your MS SQL server instance
If your databaseName value is correct, then use this: DriverManger.getconnection("jdbc:sqlserver://ServerIp:1433;user=myuser;password=mypassword;databaseName=databaseName;")
The latest JDBC MSSQL connectivity driver can be found on
JDBC 4.0
The class file should be in the classpath. If you are using eclipse you can easily do the same by doing the following -->
Right Click Project Name --> Properties --> Java Build Path -->
Libraries --> Add External Jars
Also as already been pointed out by #Cheeso the correct way to access is jdbc:sqlserver://server:port;DatabaseName=dbname
Meanwhile please find a sample class for accessing MSSQL DB (2008 in my case).
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class ConnectMSSQLServer
{
public void dbConnect(String db_connect_string,
String db_userid,
String db_password)
{
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(db_connect_string,
db_userid, db_password);
System.out.println("connected");
Statement statement = conn.createStatement();
String queryString = "select * from SampleTable";
ResultSet rs = statement.executeQuery(queryString);
while (rs.next()) {
System.out.println(rs.getString(1));
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)
{
ConnectMSSQLServer connServer = new ConnectMSSQLServer();
connServer.dbConnect("jdbc:sqlserver://xx.xx.xx.xxxx:1433;databaseName=MyDBName", "DB_USER","DB_PASSWORD");
}
}
Hope this helps.
Named instances?
URL: jdbc:sqlserver://[serverName][\instanceName][:portNumber][;property=value]
Note: backward slash
You can try the following. Works fine in my case:
Download the current jTDS JDBC Driver
Put jtds-x.x.x.jar in your classpath.
Copy ntlmauth.dll to windows/system32. Choose the dll based on your hardware x86,x64...
The connection url is: 'jdbc:jtds:sqlserver://localhost:1433/YourDB' , you don't have to provide username and password.
Hope that helps.

Categories