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: Is this the way to work with try with resources Date: Wed, 09 Aug 2017 19:37:57 +0200 Organization: Decebal Computing Lines: 106 Message-ID: <87y3qstzey.fsf@munus.decebal.nl> References: <87poc6wb9n.fsf@munus.decebal.nl> <87lgmtwels.fsf@munus.decebal.nl> <8760dxuhzl.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="75662a87a83d79e99d1b79ff65a19ab5"; logging-data="19776"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18tnb6TOP5OH+92E2b0LH2VWK5V7GthTIc=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) Cancel-Lock: sha1:470+LOqq8kzG8z+6M49RQil+P90= sha1:ZpsGLHG1IdZWgGz2ZrG6MVjbCeo= X-Homepage: http://www.decebal.nl/ Xref: csiph.com comp.lang.java.programmer:37113 Andreas Leitgeb writes: > Cecil Westerhof wrote: >> Andreas Leitgeb writes: >>> Cecil Westerhof wrote: >>>> private static void statistics() { >>>> try (ResultSet rsTotal = executeQuery(COUNT_TOTAL_PROV); >>>> ResultSet rsUnused = executeQuery(COUNT_UNUSED_PROV); >>>> ResultSet rsUsed = executeQuery(COUNT_USED_PROV)) { >>> and >>>> private static ResultSet executeQuery(String query) throws SQLException { >>>> return conn.createStatement().executeQuery(query); >>>> } >>> So, if one of the queries fails, what will happen to the statements >>> created so far? >>> Or, rather, what will *not* happen to them? >> If I interpreted try with resources correctly they are destroyed and >> nothing is done with them. > > This claim is self-contradictory. They cannot be both, "destroyed" and > "nothing done with them" at the same time. Sadly communication is not my strong suit. I mend: they are not used to retrieve values and are destroyed. The latter is not true I understand from your explanation. > Anyway, I think, we're conflating two aspects here: > 1.) your app is a simple client tool, which wouldn't really need any > error-handling with explicit cleanup at all. It could just System.exit() > for any exception, and all cleanup will be cared for. > 2.) The discussion on how to do try-with-ressources *correctly*. At the moment 1 is the case, but I also want to do 2: as the twig is bent the tree is inclined. > I'd prefer to stick with "2.)" and ignore the fact that your specific > task doesn't really demand correctness. Ok? (Otherwise there's no point > in participating in the discussion any longer.) OK. :-D > Now, in that snippet above, it would (3 times) create a statement, then execute > a query to get a resultset. If one of the queries went wrong, then the > try would auto-close any previously obtained resultsets, but it would not > do anything on the statements - in particular: not clean them up. > > So, if instead it were a long running server app, it would leak up to > three statements each time your proc is run, until it eventually > closes and reopens the connection. Luckily I created a class SQLite3 and changed all my: ResultSet rsTotal = executeQuery(COUNT_TOTAL_PROV) to: ResultSet rsTotal = sqlite3Conn.executeQuery(COUNT_TOTAL_PROV) Where sqlite3Conn is an instance of SQLite3. I had there the following function: public ResultSet executeQuery(String query) throws SQLException { return conn.createStatement().executeQuery(query); } but I now changed that to: public ResultSet executeQuery(String query) throws SQLException { try (Statement stmt = conn.createStatement()) { return stmt.executeQuery(query); } } This should take care of the leakage. By the way is there a way to ‘find’ all open Statements? That could be used to verify if a long running application is leaking resources. >>>> format = String.format("There are %%,%dd %%-6s proverbs.%%n", >>>> String.format("%,d", count).length()); >>>> System.out.printf(format, count, "total"); >>> What's the point of determining the length of e.g. "1,234,567" just to >>> set it as the length for a "%,d", which would obviously produce exactly >>> that length, anyway? >> Because I use it for the second and third. > > Ah, first row is always the widest value? Ok, that's a > justification. Yep, total = used + notUsed. So both cannot be longer as total. > But even then I'd probably have used: > int maxLen = String.format("%,d", count).length(); // first count is largest > format = "There are %," + maxLen + "d %-6s proverbs.%n"; > for slightly better readability. You are right: I implemented it. Thanks for the clarification and the readability. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof