Result Set resource leak even though I am closing the RS? - java

I am getting 'Resource leak: 'rsHP' is not closed at this location' everywhere I use a rsHP = stmt.executeQuery(query);
Here is a basic layout of what this method does...
public static void method(String x, Connection conn){
Statement stmtHP = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rsHP = null;
try{
----ALGORITHM IN HERE------
****This is the general form of this method*****
queryHP = "select * from SOMETABLE where SOMETHING = 'blah'";
rsHP = stmtHP.executeQuery(queryHP);
while(rsHP.next()){
List.add(rsHP.getString("COLNAME"));
}
.
.
repeats for 8 different queries
.
.
queryHP = "select * from SOMEOTHERTABLE where SOMETHINGELSE = 'blah2'";
rsHP = stmtHP.executeQuery(queryHP);
while(rsHP.next()){
List.add(rsHP.getString("NEWCOLNAME"));
}
}catch(Exception e){
System.out.println("Hey dumbo you suck, Exception Found");
rsHP.close();
stmtHP.close();
conn.close();
}finally{
rsHP.close();
stmtHP.close();
// connection gets closed later if no exceptions thrown
}
}// end method
At the end here I am clearly closing all my stuff. I am confused as to how I have a memory leak if it is literally impossible for my method to terminate without closing the RS outside of an error being thrown.

Connection#createStatement() throws an SQLException so this code would not compile at all.
I suggest you change the signature of the method to
public static void method(String x, Connection conn) throws SQLException
For the resource leak, I guess using the following logic will help you
try{
// code
rsHP.close();
conn.close();
}catch(Exception e){
// StackTrace
}finally{
if (rsHP != null) rsHP.close();
if (conn != null) conn.close();
}

Related

Closing Resultset, statement and Connection [duplicate]

Consider the code:
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.createStatement(myQueryString);
rs = ps.executeQuery();
// process the results...
} catch (java.sql.SQLException e) {
log.error("an error!", e);
throw new MyAppException("I'm sorry. Your query did not work.");
} finally {
ps.close();
rs.close();
}
The above does not compile, because both PreparedStatement.close() and ResultSet.close() throw a java.sql.SQLException. So do I add a try/catch block to the finally clause? Or move the close statements into the try clause? Or just not bother calling close?
In Java 7, you should not close them explicitly, but use automatic resource management to ensure that resources are closed and exceptions are handled appropriately. Exception handling works like this:
Exception in try | Exception in close | Result
-----------------+--------------------+----------------------------------------
No | No | Continue normally
No | Yes | Throw the close() exception
Yes | No | Throw the exception from try block
Yes | Yes | Add close() exception to main exception
| | as "suppressed", throw main exception
Hopefully that makes sense. In allows pretty code, like this:
private void doEverythingInOneSillyMethod(String key)
throws MyAppException
{
try (Connection db = ds.getConnection()) {
db.setReadOnly(true);
...
try (PreparedStatement ps = db.prepareStatement(...)) {
ps.setString(1, key);
...
try (ResultSet rs = ps.executeQuery()) {
...
}
}
} catch (SQLException ex) {
throw new MyAppException("Query failed.", ex);
}
}
Prior to Java 7, it's best to use nested finally blocks, rather than testing references for null.
The example I'll show might look ugly with the deep nesting, but in practice, well-designed code probably isn't going to create a connection, statement, and results all in the same method; often, each level of nesting involves passing a resource to another method, which uses it as a factory for another resource. With this approach, exceptions from a close() will mask an exception from inside the try block. That can be overcome, but it results in even more messy code, and requires a custom exception class that provides the "suppressed" exception chaining present in Java 7.
Connection db = ds.getConnection();
try {
PreparedStatement ps = ...;
try {
ResultSet rs = ...
try {
...
}
finally {
rs.close();
}
}
finally {
ps.close();
}
}
finally {
db.close();
}
If you're really hand-rolling your own jdbc it definitely gets messy. The close() in the finally needs to get wrapped with its own try catch, which, at the very least, is ugly. You can't skip the close, although the resources will get cleared when the connection is closed (which might not be right away, if you're using a pool). Actually, one of the main selling points of using a framework (e.g. hibernate) to manage your db access is to manage the connection and result set handling so you don't forget to close.
You can do something simple like this, which at least hides the mess, and guarantees that you don't forget something.
public static void close(ResultSet rs, Statement ps, Connection conn)
{
if (rs!=null)
{
try
{
rs.close();
}
catch(SQLException e)
{
logger.error("The result set cannot be closed.", e);
}
}
if (ps != null)
{
try
{
ps.close();
} catch (SQLException e)
{
logger.error("The statement cannot be closed.", e);
}
}
if (conn != null)
{
try
{
conn.close();
} catch (SQLException e)
{
logger.error("The data source connection cannot be closed.", e);
}
}
}
and then,
finally {
close(rs, ps, null);
}
For file I/O, I generally add a try/catch to the finally block. However, you must be careful not to throw any exceptions from the finally block, since they will cause the original exception (if any) to be lost.
See this article for a more specific example of database connection closing.
Don't waste your time coding low-level exception management, use an higher-level API like Spring-JDBC, or a custom wrapper around connection/statement/rs objects, to hide the messy try-catch ridden code.
Also note:
"When a Statement object is closed, its current ResultSet object, if one exists, is also closed. "
http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Statement.html#close()
It should be sufficient to close only the PreparedStatement in a finally, and only if it is not already closed. If you want to be really particular though, close the ResultSet FIRST, not after closing the PreparedStatement (closing it after, like some of the examples here, should actually guarantee an exception, since it is already closed).
I usually have a utility method which can close things like this, including taking care not to try to do anything with a null reference.
Usually if close() throws an exception I don't actually care, so I just log the exception and swallow it - but another alternative would be to convert it into a RuntimeException. Either way, I recommend doing it in a utility method which is easy to call, as you may well need to do this in many places.
Note that your current solution won't close the ResultSet if closing the PreparedStatement fails - it's better to use nested finally blocks.
Building on #erickson's answer, why not just do it in one try block like this?
private void doEverythingInOneSillyMethod(String key) throws MyAppException
{
try (Connection db = ds.getConnection();
PreparedStatement ps = db.prepareStatement(...)) {
db.setReadOnly(true);
ps.setString(1, key);
ResultSet rs = ps.executeQuery()
...
} catch (SQLException ex) {
throw new MyAppException("Query failed.", ex);
}
}
Note that you don't need to create the ResultSet object inside the try block as ResultSet's are automatically closed when the PreparedStatement object is closed.
A ResultSet object is automatically closed when the Statement object
that generated it is closed, re-executed, or used to retrieve the next
result from a sequence of multiple results.
Reference: https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
If your are using Java 7 you can use the improvements in the exception handling mechanisms in those classes that implement AutoCloseable (i.e. PreparedStatement, Resultset)
You might also find this question interesting: Closing ResultSet in Java 7
I know this is an old question, but just in case someone is looking for the answer, java now has the try-with-resouce solution.
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
Do no omit calling close. It may cause problems.
I prefer adding try/catch block to the finally.
focus finally clause,
finally {
try {
rs.close();
ps.close();
} catch (Exception e) {
// Do something
}
}
I think you have to modify 2 points.
First, use try & catch again in fainlly clause.
Second, do rs.close() before doing ps.close().
fly1997#naver.com
Probably an old (though simple) way to do things, but it still works:
public class DatabaseTest {
private Connection conn;
private Statement st;
private ResultSet rs;
private PreparedStatement ps;
public DatabaseTest() {
// if needed
}
public String getSomethingFromDatabase(...) {
String something = null;
// code here
try {
// code here
} catch(SQLException se) {
se.printStackTrace();
} finally { // will always execute even after a return statement
closeDatabaseResources();
}
return something;
}
private void closeDatabaseResources() {
try {
if(conn != null) {
System.out.println("conn closed");
conn.close();
}
if(st != null) {
System.out.println("st closed");
st.close();
}
if(rs != null) {
System.out.println("rs closed");
rs.close();
}
if(ps != null) {
System.out.println("ps closed");
ps.close();
}
} catch(SQLException se) {
se.printStackTrace();
}
}
}
I use this..
finally
{
if (ps != null) ps.close();
if (rs != null) rs.close();
}

Potential null pointer access. The variable may be null at this location. java.lang.NullPointerException [duplicate]

This question already has answers here:
Handling a null Connection in finally
(3 answers)
Closed 5 years ago.
I know a lot of similar topics exist about this error but I tried some suggestions and my problem is still not saved.
I'm following this tutorial: https://www.youtube.com/watch?v=B3gEbC37DAM&list=PL1A506B159E5BD13E&index=2
Here is my code:
public class JdbcDaoImpl {
public Circle getCircle(final int circleId) {
Connection conn = null;
try {
String driver = "org.apache.derby.jdbc.ClientDriver";
Class.forName(driver).newInstance();
conn = DriverManager.getConnection("jdbc:derby//localhost:1527//db");
PreparedStatement ps = conn.prepareStatement("SELECT * FROM circle where id= ?");
ps.setInt(1, circleId);
Circle circle = null;
ResultSet rs = ps.executeQuery();
if (rs.next()) {
circle = new Circle(circleId, rs.getString("name"));
}
rs.close();
ps.close();
return circle;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
conn.close();
} catch (SQLException e) {
}
}
}
}
On "conn.close();" it says: Potential null pointer access. The variable may be null at this location.
And I have this error when i run the program: Exception in thread "main" java.lang.NullPointerException
I tried solutions i saw on similar topics like this one:
if(conn!=null){
conn.close();
}
but i still have errors.
Thank you in advance for your help !
Finally Block is always executed while you are using try catch, where you can get a potential NullPointerException is when conn = DriverManager.getConnection("jdbc:derby//localhost:1527//db"); throws NullPointerException which is caught by your catch (Exception e) and then finally block is starting to be executed where you do conn.close(), but your conn object is NULL which throws again NullPointerException which is not caught , cos you are catching catch (SQLException e)
You do not need to explicitly load the driver (Class.forName), assuming you are using Java >= 1.6.
You can use try-with-resources to manage the AutoCloseable objects (Connection, PreparedStatement, and ResultSet), so your code can be written as:
public Circle getCircle(final int circleId) {
try (Connection conn = DriverManager.getConnection("jdbc:derby//localhost:1527//db");
PreparedStatement ps = conn.prepareStatement("SELECT * FROM circle where id= ?")){
ps.setInt(1, circleId);
Circle circle = null;
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
circle = new Circle(circleId, rs.getString("name"));
}
}
return circle;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
This also guarantees all resources are closed properly, which solves a lot of issues that can arise because of resource leaks.
The problem was that getConnection could throw an Exception, leaving conn as null, which would cause a null pointer when you later tried to close it in the finally block.
The reason why conn can be null is simple. If code executed before conn is asigned, ie before this code runs successfully:
String driver = "org.apache.derby.jdbc.ClientDriver";
Class.forName(driver).newInstance();
conn = DriverManager.getConnection("jdbc:derby//localhost:1527//db");
this code has to run successfully for conn not to be null, therefore you need a non-null check before calling close() on it.

java.sql.SQLException: Operation not allowed after ResultSet closed prob

i have error when i try run this code
i am try many time
i try to make delay 3 second before read next value from daabase
i have error
java.sql.SQLException: Operation not allowed after ResultSet closed
what you think about this error because i don't now about this error
and this is my code , please help me
try {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
String dbUrl = "jdbc:mysql://*******/jointdb";
String dbUsr = "****";
String dbPass = "*****";
String sql = "select * from eridb";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(dbUrl, dbUsr, dbPass);
st = conn.createStatement();
rs = st.executeQuery(sql);
while ( rs.next() ) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
String value = rs.getString("id");
jTextArea1.setText(value);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (SQLException ex) {
Logger.getLogger(KK.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
} catch (Exception e) { }
finally{
try{
if (rs != null)
rs.close();
if (st != null)
st.close();
if (conn != null)
conn.close();
}catch(SQLException e){}
}
You access the ResultSet in a different thread. By the time it's called, the original thread has finished its try block, moved on to the finally, and closed the ResultSet.
It looks like your Thread is a separate process in your main code. Your main code will run in parallel with your thread.
Perhaps you join the thread you create with the main code, so the main code can wait for the thread to end before it continues to close the result set. To achieve this try giving your thread a reference for example thread1 and then in main code you can add the following statement.
thread1.join();
As per definition, SwingUtilities.invokeLater will run asynchronously after all AWT events are processed (documentation here).
So, most probable, is that the finally block is reached, before the Runnable code inside SwingUtilities.invokeLater is executed.
I see no need to execute the record processing asynchronously, I'd recommend you to read and fill the Jtextarea without detaching it from the current thread.

Closing Connection, PreparedStatement, and ResultSet all in one call

Is there anything wrong in closing my connection resources like this? I seem to still have idle connections in postgres running.
public void doSomething(){
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
con = getConnection();
ps = con.prepareStatement("sql here");
....
rs = ps.executeQuery();
...
} catch(Exceptions stuff){
} finally {
closeAll(con,ps,rs);
}
}
public void closeAll(Connection con, PreparedStatement ps, ResultSet rs){
try{
if(rs != null){
rs.close();
}
if(ps != null){
ps.close();
}
if(con != null){
con.close();
}
} catch(SQLException e){
....
}
}
Practice the Best Practice
Yes, their is a problem in closing connection the way you have closed.
Suppose, an exception occurred while closing ResultSet object the rest things would not be closed
Second, suppose if everything goes fine, still you are holding other connection (etc) you are not using, it adds to the burden to the JVM, Database, Memory manager etc
It is recommended to use " try(){} with resource " feature available in JAVA 7 or if you are using JAVA 6 close them when it is no longer needed.

How to Correctly Close Resources

As I was cleaning up some code, FindBugs pointed me to a bit of JDBC code that uses Connection, CallableStatement, and ResultSet objects. Here's a snippet from that code:
CallableStatement cStmt = getConnection().prepareCall("...");
...
ResultSet rs = cStmt.executeQuery();
while ( rs.next() )
{
...
}
cStmt.close();
rs.close();
con.close();
FindBugs pointed out that these should be within a finally block. I started refactoring my code to do this and I started to wonder how to handle the code within the finally block.
It's possible that the creation of the CallableStatement of Connection objects would throw an exception, leaving my ResultSet object as null. When I try to close the ResultSet, I'd get a NullPointerException and my Connection would, in turn, never get closed. Indeed, this thread brings up the same concept and shows that wrapping your close() invocations in a null check is a good idea.
But what about other possible exceptions? According to the Java API spec, Statement.close() can throw a SQLException "if a database error occurs". So, even if my CallableStatement is not null and I can successfully call close() on it, I might still get an exception and not have a chance to close my other resources.
The only "fail safe" solution I can think of is to wrap each close() invocation in its own try/catch block, like this:
finally {
try {
cStmt.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
try {
rs.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
try {
con.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
}
Boy, if that doesn't look awful. Is there a better way to go about this?
I think the best answer has already being mentioned, but I thought it could be interesing to mention that you could consider the new JDK 7 feature of autoclosable resources.
try{
try(Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/hrdb", "obiwan", "kenobi");
Statement stm = conn.createStatement();
ResultSet rs = stm.executeQuery("select name from department")) {
while(rs.next()){
System.out.println(rs.getString("name"));
}
}
}catch(SQLException e){
//you might wanna check e.getSuppressed() as well
//log, wrap, rethrow as desired.
}
Not all of us can migrate to JDK 7 now, but for those who can start playing with the developer preview, this offer an interesting way of doing things and certainly may deprecate other approaches in the near future.
Use Lombok's cleanup, if you can:
#Cleanup
Connection c = ...
#Cleanup
statement = c.prepareStatement(...);
#Cleanup
rs = statement.execute(...);
This works translates to three nested try-finally blocks and works fine with exception. Never ever swallow an exception without a very good reason!
An alternative:
Write an own utility method like this:
public static void close(ResultSet rs, Statement stmt, Connection con) throws SQLException {
try {
try {
if (rs!=null) rs.close();
} finally {
if (stmt!=null) stmt.close();
}
} finally {
if (con!=null) con.close();
}
}
and use it in
try {
Connection con = ...
Statement stmt = ...
ResultSet rs = ...
} finally {
close(rs, stmt, con);
}
and let the Exception bubble up or handle it as you want.
Well basically that is what you do except you first of all don't necessarily swallow the exception (you can null check and at least LOG the exception). Second, you can set up a nice utility class with things like
public static void close(ResultSet rs) {
try { if (rs != null) rs.close();
} catch (SQLException (e) {
log.error("",e);
}
}
Then you just static import that class.
your finally becomes something like
finally {
close(resultset);
close(statement);
close(connection);
}
which really isn't that hideous.
You only have to close the Connection.
try
{
cStmt.close();
}
catch(Exception e)
{
/* Intentionally Swallow Exception */
}
From docs.oracle.com:
A Statement object is automatically closed when it is garbage collected. When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
Calling close() on a Connection releases its database and JDBC resources.
The only way I know to hide all that ugly try-catch boilerplate code is to utilize something like Spring's JBDC Template.
You can wrap one block into another block:
try{
Connection c = ...
try{
statement = c.prepareStatement(...);
try{
rs = statement.execute(...);
}finally{
rs.close();
}
}finally{
statement.close()
}
}finally{
c.close();
}
}catch(SQLException e){}
Use the lowermost catch-block for everything that might crop up

Categories