how to handle an exception occured in finally block - java

In the following code snippet,
try
{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e)
{
//handle exception
}
finally
{
try{ stmt.close(); }
catch(SQLException ignore){}
}
what happens when an exception occurs in the finally block while executing stmt.close();.
Is there a better way to handle these kind of problems?

sometimes connections is not open because of some exception but finally block close that connection. To avoid this Exception check out following code.
try{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}catch(SQLException e){
//handle exception
}finally{
try{
if(stmt != null){
stmt.close();
}
}
catch(SQLException ignore){}
}

finally
{
if( stmt != null ) {
try {
stmt.close();
}
catch(SQLException ex ) {
ex.printStackTrace();
}
}
}

Problems which might occur is that a statement isn't closed and then you will get an error when trying to reuse it.
try:
Statement stmt = null;
try {
stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e) {
//handle exception
}
finally
{
try{ if(stmt!=null)stmt.close(); }
catch(SQLException ignore){}
}

Usually when an exception occur we wrap it over our User defined exception and throw.
Similarly u need to throw ur own exception, when an exception occurs in finally also.
try
{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e)
{
//handle exception
throw MyOwnException(e,"My message");
}
finally
{
try{ stmt.close(); }
catch(SQLException ignore)
{
throw MyOwnException(ignore,"My message");
}
}

Related

SonarLint is still showing blocker errors even though we have handled the statement, Connection closes in finally block

SonarLint is showing below errors:
'Use try-with-resources or close this "Statement" in a "finally" clause.'
'Use try-with-resources or close this "Connection" in a "finally" clause.'
blocker errors even though we have closed the Statement stmt, Connection con in finally block.
Please find the sample code.
public String getProductNumber() throws BusinessDelegateException {
String productNo = null;
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
String query = //some query
try {
DataSource ds = getDataSource();
con = ds.getConnection();
stmt = con.createStatement();
rs = stmt.executeQuery(query);
productNo =.......
....................
}catch (Exception e) {
String errorMsg = "Error occured in getProductNumber()";
throw new BusinessDelegateException(errorMsg, e);
}finally{
try {
if(rs != null)
rs.close();
if (stmt != null)
stmt.close();
if (con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return productNo;
}
We were able to fix the issue by modifying the finally block in below manner. But still it seems like repetition of catch blocks. Any other way we can fix this?
finally{
try {
if(rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (stmt != null)
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Without try-with-resources you can only improve the code by using methods for re-usability, call main method:
closeResources(rs, stmt, con);
Which will call each for each resource a different method for example Statement:
public void closeResource(Statement stmt) {
if (stmt != null) {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
BTW, you better use logger instead of e.printStackTrace()
For complete solution, you can check extensive example which add resources in array and close them in a loop:
for (Closeable resource : resources) {
try {
resource.close();
Use Try-with-resources. This is the best option.

java.sql.SQLException: Invalid state, the CallableStatement object is closed

The code below generates this exception:
java.sql.SQLException: Invalid state, the CallableStatement object is closed.
at net.sourceforge.jtds.jdbc.JtdsCallableStatement.checkOpen(JtdsCallableStatement.java:120)
at net.sourceforge.jtds.jdbc.JtdsStatement.getConnection(JtdsStatement.java:1207)
at net.sourceforge.jtds.jdbc.JtdsResultSet.getConnection(JtdsResultSet.java:409)
at net.sourceforge.jtds.jdbc.JtdsResultSet.close(JtdsResultSet.java:470)
at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.close(DelegatingResultSet.java:152)
at
This code below sometimes generates the error above, but sometimes does not:
private void doRequest(HttpServletRequest request) throws IOException, ServletException {
CallableStatement stmt = null;
ResultSet rs = null;
String someString;
try {
this.connectDB();
stmt = this.conn.prepareCall("{call sp_SomeSP1(?)}");
stmt.setLong(1, someFunc());
rs = stmt.executeQuery();
while (rs.next()) {
if (rs.getInt(1)==someOtherFunc()) {
someString = rs.getString(2);
break;
}
}
stmt = conn.prepareCall("{call sp_someSP(?, ?)}");
stmt.setLong(1, someFunc());
stmt.setTimestamp(2, new Timestamp(getFrom().getTime()));
rs = stmt.executeQuery();
if (rs.next()) {
lastUpdated = rs.getTimestamp("LastUpdated");
}
request.setAttribute("lastUpdated", lastUpdated);
LOGGER.debug("Forwarding to view...");
getServletContext().getRequestDispatcher("/SomeJSP.jsp").forward(this.request, this.response);
} catch (NamingException e) {
LOGGER.error("Database connection lookup failed", e);
sendError("Server Error");
} catch (SQLException e) {
LOGGER.error("Query failed", e);
sendError("Server Error");
} catch (IllegalStateException e) {
LOGGER.error("View failed", e);
} finally {
try {
if (rs!=null) rs.close();
} catch (NullPointerException e) {
LOGGER.error("Result set closing failed", e);
} catch (SQLException e) {
LOGGER.error("Result set closing failed", e);
}
try {
if (stmt!=null) stmt.close();
} catch (NullPointerException e) {
LOGGER.error("Statement closing failed", e);
} catch (SQLException e) {
LOGGER.error("Statement closing failed", e);
}
try {
this.closeDB();
} catch (NullPointerException e) {
LOGGER.error("Database connection closing failed", e);
} catch (SQLException e) {
LOGGER.error("Database connection closing failed", e);
}
}
What this means is that doRequest() most of the time works properly, but sometimes we get HTTP error 500, and if we check tomcat logs we see:
java.sql.SQLException: Invalid state, the CallableStatement object is closed.
You seem to be using a member variable with a Servlet (the conn variable). however, Servlets can normally be called by multiple threads simultaneously. how are you ensuring that multiple threads are not accidentally using/closing the same Connection?
stmt.setLong(1, someFunc());
stmt.setTimestamp(3, new Timestamp(getFrom().getTime()));
It will be
stmt.setLong(1, someFunc());
stmt.setTimestamp(2, new Timestamp(getFrom().getTime()));
Seeing this error message org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.close in the stack trace, it looks like you are getting error while closing the resultset.
I would advice you to change your resultset check if condition to check whether result set is still open before closing it as:
if (rs!=null && ! rs.isClosed()){
//resultset is there and not in closed state
rs.close();
}

Is that the best way to release SQLite connection in Java?

I need a good way to close SQLIte connections in Java. After a few suggestion by other users I decided to add to my code a finally block to be sure that closing operation are always executed.
public static boolean executeQuery(String query)
{
Connection conn = null;
Statement stmt = null;
try
{
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
}
catch(ClassNotFoundException e)
{
System.out.println(e);
return false;
}
catch(SQLException e)
{
System.out.println(e);
return false;
}
finally
{
try
{
stmt.close();
conn.close();
return true;
}
catch (SQLException ex)
{
System.out.println ("Errore closing connections");
return false;
}
}
}
I'm not sure that this is the best solution.
How can I optimize this for readability?
A few comments; nutshells:
Separate the SQL exceptions from the reflection exception.
Are your SQL exceptions recoverable? If not, throw an app-specific RuntimeException.
Wrap up the connection and statement close exceptions in a utility method, yours or a 3rd party's.
Don't short-change exception handling; dump the stack trace.
This leads to the following:
public static boolean executeQuery(String query) {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new DbException("Could not find JDBC driver", e);
}
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
} catch(SQLException e) {
throw new DbException("Exception during statement execution", e);
} finally {
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(stmt);
}
}
(I'm using Apache Commons' DbUtils for its closeQuietly, it checks for null (yours didn't). Your own version might throw an app-specific exception as I do here with DbException. This wraps up all your DB-related exceptions into a single exception class, which may or may not be what you need.
If you want to make sure a command is executed you have to put it alone into a try catch block:
try {
stmt.close();
}
catch (Exception ex) {
}
try {
conn.close();
}
catch (Exception ex) {
System.out.println ("Error closing connections");
return false;
}

java.sql.SQLException: General error

Getting java.sql.SQLException
java.sql.SQLException: General error
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6986)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java:3110)
at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcStatement.java:338)
at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStatement.java:253)
at com.test.Temp.main(Temp.java:29)
I am using following code
Connection con=null;
ResultSet rs=null;
Statement stmt=null;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:locator","locator","locator");
stmt=con.createStatement();
System.out.println("Before query");
String query=null;
query="select * from user_location_table";
System.out.println("after query12");
rs=stmt.executeQuery(query);
//perform certain operation....
rs.close();
stmt.close();
con.close();
} catch(Exception e) {
e.printStackTrace();
}
The exception is thrown at stmt.executeQuery(query).
user_location_table contains following fields
user_id:number not null,
latitude:number,
longitude:number,
update_time:timestamp(6)
Thanks in advance
I get it.
The error is thrown due to the use of datatype timestamp(6) in update_time.The exception is thrown whenever we try to execute the select statement containing a column with timestamp as the datatype.
Instead of the previous code we can use the following code for selecting
query="select latitude,longitude,to_char(update_time,'HH24:MI:SS'),to_char(update,time,'DD-MON-YY') from user_location_table";
This works fine,I have tested it.
Cheers!!
A couple of thoughts. If it's only happening on the first execute, it may be that there is something invalid in the db and it's being compiled. Secondly, you may have something leaking because you aren't closing your connection and statement in a finally block. So if you get an exception, you aren't closing the connections and potentially you're creating a lock on your DB.
Add a finally block and move your close statements there checking for null:
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:locator","locator","locator");
stmt=con.createStatement();
System.out.println("Before query");
String query=null;
query="select * from user_location_table";
System.out.println("after query12");
rs=stmt.executeQuery(query);
//perform certain operation....
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (stm!=null)
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con!=null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

How to correctly close resources?

I have methods that all propagate exceptions and then I have handling on one place, however I realized something.
Let's say I have method like this
public void foo() throws Exception e {
Statement stmt = createStatement();
doSomething(stmt);
stmt.close();
}
My issue is that if exception is thrown by doSometing() method the statement will not be closed, but I don't want to handle exception there. Is the right approach to have try and catch that only rethrows exception and finally to close statement?
public void foo() throws Exception e {
Statement stmt = null ;
try {
stmt = createStatement();
doSomething(stmt);
} finally {
if(stmt != null)
stmt.close();
}
}
Close it in finally block. All resources opened should be released/closed.
See this for more - http://www.ibm.com/developerworks/java/library/j-jtp03216.html
Modification to nos answer. You actually may initialize stmt before try block. That way there is no need to see if it's null, so this just suffice:
public void foo() throws Exception e {
final Statement stmt = createStatemnt( );
try {
doSomething(stmt);
} finally {
stmt.close();
}
}
Yes, you can throw the exception further
try {
stmt = createStatement();
doSomething(stmt);
}
catch (Exception e) {
throw e;
}
finally {
if(stmt != null)
stmt.close();
}

Categories