Under which circumstance would this resource be leaking? - java

Eclipse 4 gives a warning which says the stmt may potentially not be closed and cause a resource leak:
class Test {
public void test() {
PreparedStatement stmt = null;
try {
stmt = HibernateSession.instance().connection().prepareStatement("");
} catch (final SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null)
try {
stmt.close();
} catch (final SQLException e) {
e.printStackTrace();
}
}
}
}
Under which circumstance would that happen?

I guess the conclusion here is: this is an Eclipse bug?

A leak is possible if an exception is thrown when you call stmt.close() in the finally block.

The problem was that in your finally block an exception might potentially occur, which would prevent stmt from closing.
One workaround is that you can replace everything in the finally block with:
JDBCUtilities.close(stmt);
See the docs for JDBCUtilities.close. As you can see, no exception will be thrown using this utility method so you don't need to worry about resource leak. One additional benefit is that the utility method handles the null case for stmt as well so we don't need to code it ourselves.
Actually, it is good practice to use JDBCUtilities.

You need to be using Java 7's try with resources or a try-finally block:
try(stmt = HibernateSession.instance().connection().prepareStatement("")) {
}
This warning will be generated on types that inherit from AutoCloseable that are not guaranteed to be closed. (Or possible Closeable, I forget which).
Now that I see what you're asking, just write less complicated code.
Foo f = null; // don't do this, but it's what you're doing
f = new Foo();
Is what you're doing, and you found one of several situations where you actually have to pay a penalty for this extraneous work.
Furthermore your try/finally should be clean. .close() can't throw, why are you catching?
try { // don't do this
stmt.close();
}
catch(SQLException exc) {
}
Should generate an Eclipse warning telling you that you're catching something that doesn't throw. That might even be a compile error, not sure, but sounds like you would benefit from playing with Eclipse > Preferences > Compiler and reviewing what warnings are intelligent. If you don't understand a warning, google it and see if it would be helpful to you, don't just skip over it. (sort of like you did with this one).

Related

Why does try..finally block not register the original exception as suppressed?

With the following code:
try {
throw new RuntimeException ("main");
}
finally {
throw new RuntimeException ("finally");
}
I get this result:
Exception in thread "main" java.lang.RuntimeException: finally
at test.main(test.java:12)
However, with the addition of suppressed exceptions in Java 7, wouldn't it be logical for the language to register original "main" exception as suppressed when finally block itself fails with exception? Currently I have to manually emulate this:
try {
throw new RuntimeException ("main");
}
catch (RuntimeException exception) {
try {
throw new RuntimeException ("finally");
}
catch (RuntimeException exception2) {
exception2.addSuppressed (exception);
throw exception2;
}
}
to receive more useful (for understanding what's going on) result:
Exception in thread "main" java.lang.RuntimeException: finally
at test.main(test.java:13)
Suppressed: java.lang.RuntimeException: main
at test.main(test.java:9)
EDIT: To clarify what I'm wondering. Current Java version is 8, suppressed exceptions are not a brand new feature. But try..finally still doesn't incorporate them. Is there something that prevents this from happening?
Because try-with-resources is syntactic sugar and the Java compiler doesn't expand regular try-finally blocks in the same way.
Take a look at the following code:
try(FileInputStream fstream = new FileInputStream("test")) {
fstream.read();
}
When compiled and then decompiled (using IntelliJ IDEA) it looks like this:
FileInputStream fstream = new FileInputStream("test");
Throwable var2 = null;
try {
fstream.read();
} catch (Throwable var19) {
var2 = var19;
throw var19;
} finally {
if(fstream != null) {
if(var2 != null) {
try {
fstream.close();
} catch (Throwable var17) {
var2.addSuppressed(var17);
}
} else {
fstream.close();
}
}
}
Whereas this code:
FileInputStream fstream = new FileInputStream("test");
try {
fstream.read();
} finally {
fstream.close();
}
Looks exactly the same when compiled and decompiled.
Now, the case could definitely be made that all finally blocks should be expanded in the same way as is done above, but for some reason that has either been overlooked or decided against.
I suggest you open a feature request for this because I think it's a sensible feature.
This isn't an authoritative answer but it looks like such a change would either break compatibility, or try-with-resources and try-finally would be inconsistent with each other.
The semantics in try-with-resources is that the exception thrown from the try block is propagated, with the exception thrown when invoking the close() method registered as suppressed. This makes sense from a practical point of view, you want to catch your "real" exception and then maybe also deal with the resource not closing if you want to.
But in try-finally it is the exception thrown in finally that is propagated (while the one from try is "swallowed") and therefore we have a choice of three bad solutions:
Reverse the logic of try-finally to align it with try-with-resources and ruin code (or rather, bug) compatibility with all previous code.
Keep propagating the "close()" exception with the try exception registered as suppressed, making the two constructs inconsistent with each other.
Just leave everything as it is.
Subjectively I see 3 as less bad than 1 or 2, though it's fairly easy to argue otherwise. I suspect however that this was a dilemma the language developers were faced with and they happened to choose option 3.

Why does Java not support retrieval of exceptions from try/catch lost when an exception is thrown from finally?

In Java 7, the feature was added to (via getSuppressed()) get exceptions thrown from the implicit finally block of a try-with-resources statement.
There still doesn't seem to be a way (that I know of) to do the opposite - when there is an explicit finally block and that throws an exception, masking the exceptions thrown and pending from the try/catch.
Why does Java not provide functionality to get these buried/lost exceptions through a mechanism similar to getSuppressed()?
It would seem that the implementation of this functionality would be similar to that used in getSuppressed() or chained exceptions, and the provided benefit would be very useful, yet it continues to be left out of each release.
What would be the danger of making these masked exceptions available to programmers through a method call similar to getSuppressed()?
(Apologies in advance if this functionality already exists and I'm just clueless.)
The suppression thing isn't limited to try-with-resources, and you can use it for similar situations yourself. E.g., it is provided for other situations.
try-with-resources puts the logic for closing the resources behind the scenes, so you don't have direct access in your own code to dealing with any exceptions that occur during the process. So they added the "suppression" thing so they could use it in that behind-the-scenes code.
But cleverly, they didn't only make it something that could be used there. You can use it yourself, via Throwable#addSuppressed.
You can see this in the pseudo-code example given in JLS ยง14.20.3.1; here's a real code version of it:
{
SomeResource someResource = null;
Throwable primaryException = null;
try {
someResource = /*...get the resource...*/;
/*...do something...*/
}
catch (Throwable t) {
primaryException = t;
throw t;
}
finally {
if (someResource != null) {
if (primaryException != null) {
// Dealing with a primary exception, close the resource
// and suppress any exception resulting
try {
someResource.close();
}
catch (Throwable suppressed) {
primaryException.addSuppressed(suppressed);
}
}
else {
// Not dealing with a primary exception, close the
// resource without suppressing any resulting exception
someResource.close();
}
}
}
}
Note the different behaviour (Using exception A for the exception in try, exception B in finally):
In a try-with-resources exception A suppresses exception B.
In a normal try exception B masks exception A.
If you want backwards compatibility (And you ALWAYS want it), you need to make B suppress A. But that is the complete opposite of what try-with-resources does (and actually, the opposite of what most developers want).
As a workaround, you can just use the (slightly modified) code that is in the Oracle blog on how try-with-resources works:
Exception ex;
try {
doWork();
} catch (Exception e) {
ex = e;
throw(e);
} finally {
try {
doFinally();
} catch (Exception e) {
if (ex != null) {
ex.addSuppressed(e);
} else {
throw(e);
}
}
}
Obviously move the throw out of the initial catch if you want the finally exception to suppress the initial one.

Behaviour of try-catch-finally block when exceptions are thrown from both try and finally block?

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. Why is the behaviour as such? Why is the exception from try block supressed?
Only exceptions within the try portion will be handled. Anything outside this (including the finally section isn't covered by a try and as such, Exceptions aren't handled.
If you want to catch/suppress the exception inside the finally block, you need to wrap if (br != null) br.close(); with it's own try/catch block, like this:
...
} finally {
try {
if (br != null) br.close();
} catch (Exception e) {
// whatever handling
}
}
...
Also, the exception from the try block is suppressed because that's the behavior of a try block - to try something and give you a chance to recover. Since you don't catch any exceptions after your try block, no code is run in response to it.
Then, whether or not any exception is thrown, the finally block is executed. If it throws an exception, and because it's not inside a try/catch block of its own, its Exception is propagated out the method, and to the calling method.
To take the example from your comment below, as of Java 7, you'll want to refer to the documentation outlined here, and focus on the second-to-last section entitled "Supressed Exceptions", which basically says that multiple exceptions can be thrown out of a try block, up to one exception per declared resource.
As far as what happens if the resource declaration itself throws an exception, I don't have JDK7 installed, so I'm not sure. Why not put the following code in a test project (exactly as it appears, with a bogus path), see what happens, and then tell us what the result it for everyone's benefit:
try (BufferedReader br = new BufferedReader(new FileReader("a totally invalid path"))) {
return br.readLine();
}
Why is the behaviour as such? Why is the exception from try block
supressed?
Because that's the way the architecture defines it.
Because decades of experience have shown that this is the best solution to the potential ambiguity.
because a function can throw only one exception. The later exceptiobn supresses all the previuos
It can only throw one exception, and the one from the "finally" block wins, according to the spec.
Finally blocks should always be coded very defensively for this reason. See:
Is a finally block without a catch block a java anti-pattern?
Well, what behaviour would you want? There's no concept of multiple exceptions being thrown at once - so one of the exceptions would have to "win". It would be nice if there were some consistent way of representing "multiple things have gone wrong" in the language (support beyond just wrapping one exception in another) but the boat's sailed on that one.
This is one reason why Guava has Closeables.closeQuietly, so that the original exception won't be suppressed.
EDIT: Note that in Java 7, there are slightly more options with the try-with-resources feature. See the documentation for more details; it goes into detail about this specific situation.
When I checked this post, Same question as below which someone has added in comment came to me. I did bit of analysis and here is my answer.
Comment:
"That comment consists of a try-with-resources statement.Can you explain what happens when both throw exceptions?"
Answer:
It will throw exception for try block, The exception thrown from try-with-resource statement is suppressed.
Here is one quick sample program to understand the same.
class MyResource implements AutoCloseable {
public void close() throws SQLException {
throw new SQLException();
}
}
public class Try {
public static void main(final String[] args) {
try(MyResource mr = new MyResource ()) {
System.out.println("Hi");
throw new IOException();
}
catch (IOException | SQLException e) {
System.out.println("Exception raised:" + e.getClass());
System.out.println("Exception suppressed:" + e.getSuppressed()[0]);
}
}
}
The output of this program:
Hi
Exception raised: class java.io.IOException
Exception suppressed: java.sql.SQLException

Java try-finally construction

Could someone explain me some situation (example) when we can use this construction?
try{
//dangerous code here
} finally {
//always called
}
I really understand how it works but newer use in real situation.
Pretty much any time you have something like a Closeable, where you need to explicitly call close() to release the underlying resource, you want to put that call in a finally block, like:
FileReader f = whatever();
try {
// do some stuff with f
return;
}
finally {
f.close();
}
Even if no exception is thrown, and the return inside the try block is run, the resource will still be closed correctly.
try {
isWorking = true
//doStuff that might or might not succeed
} finally {
isWorking = false;
}
another example:
public void actionPressed()
{
if( isLoading )
return;
try {
isLoading= true;
doTheLoad);
} finally {
isLoading = false;
}
}
Some of the common scenarios:
Prevent resource leak:
Close IO streams and DB connections
Message logging
You might use it close database connections or any other resource - a file, hardware port, etc.
try{
// Do something I care about
} finally {
// Make sure we clean up, regardless of success or failure
}
Here's an example:
InputStream in = new FileInputStream(...);
try {
/ * use in here */
} finally {
in.close();
}
Basically, no matter what happens, in will always be closed. Without this, in could stay open until the garbage collector collects it (could be a long time). This is a problem because:
There is a limit on the number of files / network connections you can have open at once
Open network connections will continue to tie up resources on the remote end too (DB connections are a good example)
Closing an input stream also flushes it generally (flushing writes anything in the inputstream's buffer)
For instance when you read a file:
InputStream is = new FileInputStream("...");
try {
// do stuff
}
finally {
is.close();
}
This way your file is always closed, even if there is an exception.
openFile();
try {
int i = Integer.parseInt(someString);
String sub = someString.substring(2);
System.out.println(i+sub);
}
finally {
closeFile();
}
as you can see, there might several Exceptions be thrown during a code passage and you possibly don't want to catch every of them.
also there could an Error be thrown, which you should not catch!
in any way you want to close your file, before the method ends, so you put that in the finally-block
Look at this article, Java Exception Handling - Basics. Here described clearly about exception and where it is used.
This is a very common pattern:
InputStream stream = // acquire stream...
try {
// do stuff with stream that might throw...
}
finally {
IOUtils.closeQuietly(stream);
}
Note, IOUtils is a library from the Apache Commons project. You should always close the stream in a finally. closeQuietly eats any exceptions that might be thrown while trying to close the stream (which is OK because you can't do anything about it).
Especially we can use for data base connection close related code in finally block. if program throws any exception in this case DB connection will release .
This is example in JDBC.same can be applicable in session.close() in Hibernate.
try{
//dangerous code here
} catch(Exception e){
//Do some thing releted to your exception
} finally {
//close DB connection or close your hibernate session.
//always called
}
Well, let's say you open a connection to a database and make some queries. If a SQLException is raised by one of the queries, you're supposed to close the connection before doing something else. If no exception is raised, you're still supposed to close it.
So the try {} catch () {} is there to catch those SQLExceptions and do something about them, while the finally {} is there to close the connection in either case.
This would be a very common scenario, but the same is true with any resource that needs to be freed no matter what happens while using it.

Where to close statements in JDBC

I am using JDBC to retrieve data from a database. I understand that a Statement needs to be closed after it is used. However, I keep run into the same error telling me that no operation is allowed after the statement is closed. The structure of my code is like
public void foo() {
Statement;
try {
} catch{
}
Statement.close();
}
In my code, I need to call this function repeatedly. I was wondering where to close the Statement.
Thanks
According to the Javadocs:
Statement.close() Releases this Statement object's database and JDBC resources immediately instead of waiting for this to happen when it is automatically closed. It is generally good practice to release resources as soon as you are finished with them to avoid tying up database resources.
Which means you should close it after you done and not planning to use it again. I would, actually pay more attention to closing your Connection.
In your method which you say you call repeatedly you are calling Statement.close() which means that you can only use it once since after the first call you Statement is closed and cannot be used anymore.
It would be nice to see some of your code if you want a better answer
Note that JDBC resources should always be closed, so, its better to put that to the 'finally' block.
You can also consider Spring DAO usage - it is a thin wrapper on top of JDBC and covers most of JDBC boilerplate stuff.
ResultSets also need to be closed.
It sounds like you might be doing something like accessing a Blob, the Blob object often goes back through the connection to read the byte data from the database. So read all of the byte[] data before you close the connection. If that's not possible because there's too much data and you are trying to stream the bytes then you're just going to have to stick the connection somewhere safe and call close on it later.
Close statements should go into finally blocks, and be null protected - but it's such common and ugly code so stick in a static method somewhere.
public List someMethod() {
Statement stmt;
ResultSet rset;
try {
stmt = con.createStatement();
rset = stmt.executeQuery(....);
List resultList = ...create a list
// get the data from the rset
return resultList;
} catch (SQLException ex) {
throw new MyDatabaseException(ex);
} finally {
}
}
public class DatabaseUtils {
public void close(Statement stmt, ResultSet rset) {
try {
if (rset != null) {
rset.close();
}
} catch (SQLException ex) {
throw new MyDatabaseException(ex);
} finally {
if (stmt != null) {
throw new MyDatabaseException(ex);
}
}
}
}

Categories

Resources