Android App is connected to database by using JDBC library.
But DriverManager.getConnection("url") is returning null. So I tried putting "try...catch " like this:
Connection con = null;
try {
con = DriverManager.getConnection("dummy url");
System.out.println("Connected.");
}catch(ClassNotFoundException ce){
System.out.println("ClassNotFoundException ");
}catch(SQLException se){
System.out.println("SQLException ");
}catch(Exception e){
System.out.println("Exception ");
}finally {
if (con== null) {
System.out.println("Result: null");
}else{
return con;
}
}
Output:
Result: null
If URL is wrong , Try...Catch should be cached some exception. But it skipped all exceptions and getConnection("dummy url") returned null.
Although I tried to change to real url however the problem is not different.
Updated: I modified some code
add condition in scope of finally
move declaration con varialbe to out of scrope.
It still cannot catch any exception
That con variable declared in the try block is out of scope in the catch and finally clauses.
The only way that this code could compile is if you have declared another con variable ... probably as a field of the enclosing class.
This explains why you are seeing con with a null value when that apparently cannot happen. You are printing the other con variable.
Note that DriverManager.getConnection(...) won't ever return null. The javadoc states that it returns a Connection object, and nothing else. If the method could return null, the documentation would say so explicitly.
UPDATE Once you have corrected the scoping problem with con. It is now possible that the problem is that you are not catching the exception. Specifically, it could be an Error exception, which might arise if there was a problem loading (say) the appropriate JDBC driver class.
Change
}catch(ClassNotFoundException ce){
System.out.println("ClassNotFoundException ");
}catch(SQLException se){
System.out.println("SQLException ");
}catch(Exception e){
System.out.println("Exception ");
to
} catch(Throwable e) {
e.printStackTrace();
}
(If you catch an exception for diagnostic purposes, you should always print or log the stacktrace!)
Related
I get an exception that the database is locked and I try to close connection and statement, but here is the problem unreachable statement in try block.
public static ResultSet getData (String query){
try {
Connection conn = ConnectionProvider.connect();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
return rs;
try {
conn.close();
st.close();
rs.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
return null;
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
System.out.println(e);
return null;
}
Everything you do after the first return statement in the outer try block can never be reached. The second try block will never be executed, therefore you have some unreachable code here.
I think what you want to do is this:
try {
Connection conn = ConnectionProvider.connect();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
try {
conn.close();
st.close();
rs.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
return null;
}
return rs;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
System.out.println(e);
return null;
}
Although I will say that this may just not be the correct place to use the try-catch. Maybe what you should do here is throw the possible exceptions back to whoever calls this method instead - usually nested try-catch blocks are very rarely actually used/needed in this way. Also if you encounter an exception, you just return null, instead of handling what this means for the rest of your application.
What you could also try is, assuming that at this point your query was successful:
try {
Connection conn = ConnectionProvider.connect();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
try {
conn.close();
st.close();
rs.close();
} catch (Exception e) {
throw e;
} finally {
return rs;
}
} catch (Exception e) {
throw e;
}
Though for this approach you should really think about what you need to happen in each error case.
As an additional side note, even though I'm aware that many people ignore this:
Always try to use the proper class for the Exceptions you expect in a catch-block, and if it's only for readabilities sake.
There are several things to improve in the piece of code you post.
First, you need to close the resources (Connection, Statement and ResultSet) in reverse order with respect to the opening order. So, first you should close the ResultSet, second the Statement, and finally the Connection.
Closing in the order you are doing might cause problems when closing Statement / ResultSet with the Connection already closed.
By other hand, starting in Java 7, you have the try-with-resources construct, that closes resources for you. You can take a look at The try-with-resources Statement docs.
As far as I understood, closing the connection objects in finally block is the best practice. However, if rs.close() / ps.close() throws an exception at the finally block, it won't execute the conn.close(). Therefore I used to close connections at two positions (as in sample provided), once directly after use, and secondly additionally in a finally-block using a check for null. But some consider block 1 as redundant code. Is it really redundant or is there proper way to address this issue without closing the connection in two places?
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection(); // geting the connection object
ps = connection.prepareStatement(INSERT_QUERY);
rs = ps.executeQuery();
// some logic here ...
// ---- block 1 ----
ps.close()
ps = null;
rs.close();
rs = null;
conn.close();
conn = null;
// ---- end block 1 ----
} catch (SQLException e) {
// exception handling ...
} finally {
closeQuietly(conn, ps, rs);
}
private void closeQuietly(Connection connection, PreparedStatement ps, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {}
}
}
is there proper way to address this issue without closing the connection in two places?
Yes:
try (Connection conn = dataSource.getConnection(); // geting the connection object
Prepared Statement ps = connection.prepareStatement(INSERT_QUERY);
ResultSet rs = ps.executeQuery();) {
// ...
}
This is the 'try-with-resources' syntax. Everything declared inside the () after the try is guaranteed to be closed.
Yes, it would be called twice if everything goes fine with your code. That's the reason, people prefer to close any sort of connections (jdbc, stream etc) in the finally block.
As you know, The finally block gets executed whether program executed correctly or not.
So, I would recommend that you should not closing code after the use.
Jitendra
Block 1 is indeed redundant, as closeQuietly will always run due to the finally block.
closeQuietly does the right thing:
As each resource is surrounded by its own try-catch block, the code to cleanup the connection will run even if the block closing the statement or resultset throw exceptions: Those exceptions will be caught and ignored by their try-catch blocks.
I am using Netbeans( I have jar file in my library) to connect to SQL Server and wondering why nothing is happening. I am can see the following message printing on my screen Loading the Driver for SQL Server at xx.xx.x.xxx and nothing happens after that:
I am also trying to test whether the connection is null or not but for some reason System.out.println("Connection Successful !"); is not printing anything and hence I suspect it's not getting connected. Could anyone please see what's going on here:
My code is here:
try {
String QueryStringGlobalAlertLogs = "";
try{
System.out.println("Loading the Driver for SQL Server at xx.xx.x.xxx");
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
catch(java.lang.ClassNotFoundException e){
return 0;
}
connRemoteforGlobal = java.sql.DriverManager.getConnection("jdbc:sqlserver://xx.xx.x.xxx;databaseName=Alerts",RemoteSQLServerUser,RemoteSQLServerPass);
if(connRemoteforGlobal != null)
{
System.out.println("Connection Successful !");
}
QueryStringGlobalAlertLogs = // My INSERT Query here
}// End of first try
catch(SQLException ex2){
ex2.printStackTrace();
System.out.println("Error Trace in Connection : " + ex2.getMessage());
}
You must catching Class.forName and getConnection together.
try this:
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
DriverManager.getConnection("jdbc:sqlserver://xx.xx.x.xxx;databaseName=Alerts",RemoteSQLServerUser,RemoteSQLServerPass);
}catch(SQLException e1){
// handle error
}catch(ClassNotFoundException e2){
// handle error
}
Should I close the statement before the connection? And the resultset before the statement?
Or is it all the other way around?
Connection conn = null;
Statement st = null;
Resultset rs = null;
try {
// Do stuff
} catch (SQLException e) {
// Do stuff
}
finally {
if (rs != null) rs.close();
if (st != null) st.close();
if (conn != null) conn.close();
}
Or
Connection conn = null;
Statement st = null;
Resultset rs = null;
try {
// Do stuff
} catch (SQLException e) {
// Do stuff
}
finally {
if (conn != null) conn.close();
if (st != null) st.close();
if (rs != null) rs.close();
}
Close the result set, then the statement, then the connection.
In other words, close everything down on a last-in-first-out basis.
You should close the resources in the reverse of the order you opened (as if these resources are on a stack).
With Java 7 try-with-resources, the ideal way is:
try (
Connection conn = somethingThatGetsAConnection();
Statement st = conn.createStatement();
Resultset rs = st.executeQuery("SELECT something");
) {
// Do stuff
} catch (SQLException e) {
// Do stuff
}
And Java will take care of it for you, and it will close the resource in the reverse order. See also the Oracle tutorial on try-with-resources:
Note that the 'close' methods of resources are called in the opposite order of their creation.
You can find a more in-depth look at try-with-resources in the article Better Resource Management with Java SE 7: Beyond Syntactic Sugar
The Java Language Specification for Java 7 mentions in section 14.20.3:
Resources are initialized in left-to-right order. If a resource fails to initialize (that is, its initializer expression throws an exception), then all resources initialized so far by the try-with-resources statement are closed. If all resources initialize successfully, the try block executes as normal and then all non-null resources of the try-with-resources statement are closed.
Resources are closed in the reverse order from that in which they were initialized. A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources.
This can also be seen as a clear indication that the Java language designers consider closing resources in the reverse order they where allocated the norm.
ResultSet, Statement and then the Connection. The golden rule to JDBC connections and statements is to close in the reverse order of initiation or opening. In addition, the ResultSet is dependant on the execution of the Statement and the Statement is dependant on the Connection instance. Hence, the closing should occur in that order (ResultSet, Statement, Connection).
The first example is the right way. The problem with any other order is that closing a Statement will automatically close any underlying ResultSet as well (and same may happen for a Connection) - so you need to close the one lowest in the hierarchy first.
The close() methods may throw a SQLException, as #aubin pointed out. One easy solution to this problem is to use DBUtils closeQuietly() method for closing them - then you don't even need to null-check!
To solve this with minimal effort, try using Java 7's new A.R.M. (Automatic Resource Management) Blocks, also known as Try-With-Resources.
try (Connection conn = null, Statement st = null, ResultSet rs = null){
// Do stuff
} catch (SQLException e) {
// Do stuff
}
No ugly Finally or worrying about proper order, Java takes care of it for you.
Some more info regarding ARM/Try-With-Resources Blocks: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Conclusion: the order does not really matter as long as you close them individually.
From the official API specification on close() on class Connection, Statement and ResultSet:
For already closed resources, close() is a no-op:
Calling the method close on a Connection object that is already closed is a no-op.
Calling the method close on a Statement object that is already closed has no effect.
Calling the method close on a ResultSet object that is already closed is a no-op.
Closing a resource of "higher order" closes their "derived" resources:
[Connection.close()] Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically reeased.
[Statement.close()] Note:When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
You can try the following code to see if closing Connection also closes the other two resources:
// url, username, password and sql pre-defined
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try
{
conn = DriverManager.getConnection(url, username, password);
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
}
catch (SQLException e) { e.printStackTrace(); }
finally
{
if (conn != null)
{
System.out.println("conn is not null and I'm about to close it");
try
{
conn.close();
System.out.println(stmt != null && stmt.isClosed() ?
"stmt is also closed" : "stmt is alive");
System.out.println(rs != null && rs.isClosed() ?
"rs is also closed" : "rs is alive");
}
catch (SQLException e) { e.printStackTrace(); }
}
}
Hence, say if we close them in this FIFO order: Connection > Statement > ResultSet:
finally
{
if (conn != null)
{
try { conn.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
if (stmt != null)
{
try { stmt.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
if (rs != null)
{
try { rs.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
}
If a "higher order" resource is successfully closed, its "derived" resources should've been closed as well
Calling close() on these already closed resources is a no-op but is fine as no exceptions are thrown
If failed to be closed, its "derived" resources still have a chance to be closed
And you can also tell the similiar story for any other arrangements.
I'm using JODConverter to convert .xls and .ppt to .pdf format. For this i have code something like
try{
//do something
System.out.println("connecting to open office");
OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
System.out.println("connection object created");
connection.connect();
System.out.println("connection to open office successful");
//do something
if(!successful)
throw new FileNotFoundException();
}catch(Exception e){
System.out.println("hello here");
System.out.println("Caught Exception while converting to PDF ");
LOGGER.error("Error in converting media" + e.getMessage());
throw new MediaConversionFailedException();
}finally{
decode_pdf.closePdfFile();
System.out.println("coming in finally");
//do something here
}
My Output :
connecting to open office
connection object created
coming in finally
P.S. return type of method is void
How is it possible ? Even if there is some problem in connection.connect(), it s'd come in catch block. confused
Perhaps an Error was thrown. This would still result in the try block not being completed, the catch Exception block ignored and the finally block being called.
try to catch Throwable, and watch stacktrace, maybe conection.connect() threw an Error (or other custom class which also extends Throwable).
If an error of type Error occurred, or worse, of type Throwable, then your catch handler for Exception wouldn't fire. Is it possible that you're getting some sort of VM error, or OOM, or stack overflow?
If so, this would account for the output you reported.
Depending on the implementation of OpenOfficeConnection Interface various types of throwables can be expected. It is possible that one of those throwables does not extend java.lang.Exception. Try to catch java.lang.Throwable instead