tags:

views:

48

answers:

2

Is there any way to detect and handle whether a Java library is correctly releasing file-handles (via "close") from within a Java program that is using said library, short of having access to the actual library code and inserting the corresponding "finally close" statements?

If detection is feasible, is there any way to close those file-handles without a reference to the Reader (or FileInputStream) that was reading the file?

+1  A: 

Under Linux and probably some Unixes, you can use lsof to "list open files" opened by an application. You'll probably see their number increase if your app is leaking file handles. You may even hit the (default) ceiling of 1024 handles eventually.

Under Windows, there's some free similar utilities somewhere in the SysInternals suite; I think it's called "handles" or "fhandles" or such. I'll go see if I can find it...


EDIT: Ah, here it is: Handle .


EDIT: I recently ran into a similar, obscure problem with sockets (which are also a kind of file handle, at least under Linux): Turns out that even if the connection was closed, the associated file handles would not be released until Java did a garbage collection. Our app didn't go through a lot of memory, so often connection handles would pile up faster than they got cleaned up. We solved the problem by inserting a System.gc() every once in a while. The performance hit was tolerable relative to an out-and-out malfunction when the app ran out of handles.


EDIT: At its higher level, the JRE's library is of course "just" Java code, and the source code is AFAIK still being published. So if you're really desparate, you could write your own wrappers around things like FileInputStream and FileReader, etc. I believe there's a directory name in the JRE's file tree into which you can put Jars of "fiddled" classes; it's called "endorsed" or something like that. That, or you could out-and-out make source code changes to the JRE library code and build your own replacment jars for the Sun (or whatever) libraries. This is obviously not clean or highly portable. I don't have any experience of my own with such measures, nor would I recommend them.

Carl Smotricz
I am aware of lsof (and the /proc way to look at things) -- that would indeed work, in a non-portable way, for detecting the leak programmatically. I would, however, much rather a java-only solution, and ideally a java-only fix
tucuxi
Nice - I was not aware of that handle program for windows. Still, is there any within-java way to do things?
tucuxi
Gotcha. In that case, I misunderstood your question. I do, however, question your need to do this programmatically. Either you find, in a manually monitored trial run, that the program is leaking handles, and you complain to your library's manufacturer until he fixes the problem. Or you don't find evidence of leaking handles, in which case you won't need to build a kludge into your program. To answer this question: No, I don't think there's a platform neutral way to do this from within a Java program. The library doesn't exactly go out of its way to expose this stuff.
Carl Smotricz
Added yet another edit with what I consider a desperate measure.
Carl Smotricz
Points for suggesting a fix: even if it is a truly ugly one it would certainly work. If nobody else chimes in with something more beautiful, I'll mark it as the accepted answer.
tucuxi
+1  A: 

You could run FindBugs on the library.

Michael Munsey
That would require sources for the library :-(
tucuxi
http://findbugs.sourceforge.net/factSheet.html"FindBugs works by analyzing Java bytecode (compiled class files), so you don't even need the program's source code to use it."
bkail
bkail is right, you can run FindBugs on class files or on a full jar file. FindBugs will notify you of any resources that are not closed properly. That won't help you fix them, but it will let you know for sure that they exist.
Michael Munsey