Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Cecil Westerhof Newsgroups: comp.lang.java.programmer Subject: Re: Not closing a SQL(ite3) connection Date: Sat, 12 Aug 2017 10:00:46 +0200 Organization: Decebal Computing Lines: 118 Message-ID: <87k229z041.fsf@munus.decebal.nl> References: <87a839um2q.fsf@munus.decebal.nl> <874lte1pdj.fsf@munus.decebal.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: mx02.eternal-september.org; posting-host="a1c8c080b2cb6129343ef73ef98e693f"; logging-data="345"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX187/arSKLHzA+iHvb7PeBITpz29L3zYStE=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) Cancel-Lock: sha1:IOZ0k+dLxXx1ttCcB8Qbp73TRXA= sha1:3dRbFIHv/UvL9UFRibJOAO94cVc= X-Homepage: http://www.decebal.nl/ Xref: csiph.com comp.lang.java.programmer:37138 Arne Vajhøj writes: > On 8/11/2017 4:26 AM, Cecil Westerhof wrote: >> I have a strange problem. I made a class SQLite3ResultSet. There is a >> lot of stuff to be removed, but that is just to find out if it is >> doing what I think it is doing. You did not read this part? >> And the close method is (for now, because I want to test it): And also not this? >> @Override >> public void close() throws SQLite3Exception { >> System.out.println("SQLite3ResultSet: closing open resources."); >> String errorMsg = ""; >> >> try { >> stmt.close(); >> resultSet.next(); >> resultSet.close(); > > resultSet.close(); > stmt.close(); > > was rather obvious. If you read my message a bit better, you would have seen that it is not real code, but that I do things that are wrong to verify that the good code does what I think it does. >> } catch (SQLException e) { >> errorMsg += "Could not close ResultSet.\n"; >> System.out.println(errorMsg); >> } >> System.out.println("Closed resultSet."); >> try { >> stmt.close(); >> } catch (SQLException e) { >> errorMsg += "Could not close Statement belonging to ResultSet.\n"; >> System.out.println(errorMsg); >> } >> System.out.println("closed stmt"); >> System.out.println("SQLite3ResultSet: closed open resources."); >> if (!errorMsg.isEmpty()) { >> throw new SQLite3Exception(errorMsg); >> } >> } >> >> In the first try I close the stmt and then I do a resultSet.next(). I >> would expect an exception, because I closed the stmt, but I do not get >> an exception. Why not? > > There is nothing in documentation for next() requiring an exception to > be thrown (ResultSet is not closed and it may not get a database error - > maybe it does not even talk to the database). That was the problem. When using: resultSet.getInt("Count"); instead of: resultSet.next(); I get the error I expected. Now I can remove the stmt field out of my class. With this I verified that I did not get a Statement leak: @Override public void close() throws SQLite3Exception { System.out.println("SQLite3ResultSet: closing open resources."); try { Statement stmt = resultSet.getStatement(); stmt.close(); System.out.println("Closed stmt."); resultSet.getInt("Count"); System.out.println("Did getInt"); resultSet.close(); } catch (SQLException e) { throw new SQLite3Exception("Could not close ResultSet."); } System.out.println("Closed resultSet."); } I do get ‘Closed stmt, but I do not get ‘Did getInt’. So the closing of stmt works. The real method is now: @Override public void close() throws SQLite3Exception { boolean closedResultSet = false; try { Statement stmt = resultSet.getStatement(); resultSet.close(); stmt.close(); } catch (SQLException e) { if (closedResultSet) { throw new SQLite3Exception("Could not close Statement after closing ResultSet."); } throw new SQLite3Exception("Could not close ResultSet."); } System.out.println("Closed resultSet."); } The reason that I wrote this code was that I do not want to have to put a Statement and a ResultSet into my try with resources. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof