0

I have an Iterator backed by a ResultSet. I need that for a row-level post-processing. The iterator implements AutoCloseable inteface. The connection remains open up until we iterate through all the rows / iteration interrupted by the user. And everything is fine if the consumer of the iterator calls close() method explicitly or is wrapping the use of the iterator in a Java7 try block. However, if the consumer doesn't do so I can't guarantee that the connection will be returned to the pool. In C# world we would do a finalizer and call Dispose(bool) from the finalizer as a fallback option. Should we do the same in Java?

amdmax
  • 771
  • 3
  • 14
  • No. If your `Iterator` goes out of scope, the `ResultSet` will as well. So let the maintainer of the `ResultSet` (e.g. JDBC driver implementer) decide whether to track `ResultSet` instances or not. It’s not the responsibility of your `Iterator`. – Holger Mar 11 '15 at 19:28

1 Answers1

3

This kind of cleanup generally isn't done in a Java finalize() method. Failing to ensure proper disposal of a resource is a programming error; trying to clean up after bad programming is enabling the continuation of bad practices.

What is more common is a debugging option to help developers who've acknowledged they have a problem. Usually this isn't enabled by default, because of the overhead involved, but when the right flag is turned on, a stack trace is created when the resource is allocated. If finalize() is invoked without the resource being destroyed properly, the stack is logged to show the location of the leak.

There are a number of caveats around finalize(), and you should generally avoid it. One of the main problems in this case is that there's no guarantee it will ever be invoked, and even if it is, it may not be in time to help.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • I do understand the pitfalls of the finalization process such as prolongating the TTL for the object and so on. However, this type of bug (unmanaged resources management) is opening us up for a resource leak, isn't it? And without any warranties we still should throw away a baby with bathwater? I mean this bug is really hard to discover. Only under a certain load when the number of the connections you obtain from the pool is somehow limited, or the database doesn't allow any more connections created by explicitly. Does your comment still apply? – amdmax Apr 04 '15 at 16:36
  • It's hard to say whether it's applicable without understanding how you are using this `Iterator`. I can understand that you might need to adapt a `ResultSet` to `Iterator` in order to pass it to some third-party API that you can't modify; but I don't see why your code that performs this adaptation can't reliably and explicitly call `close()` on the underlying `ResultSet` after the call to the third-party API returns. – erickson Apr 06 '15 at 20:34
  • Erickson is right: it's the consumer's fault if `close()` is not called and there isn't much you can do about that. The best you can do is follow Erickson's advice of using the finalizer to check whether or not the resource was closed and log a warning in that case letting the developers know about the leak. – Paulo Dec 04 '15 at 12:29