开发者

What's a good pattern for a java unit test that ensures that you are properly closing files?

开发者 https://www.devze.com 2023-04-08 18:21 出处:网络
I have an issue in my codebase where we are not properly closing f开发者_C百科ile handles, or probably streams.We eventually get a TooManyOpenFiles exception under very heavy load.Based on the output

I have an issue in my codebase where we are not properly closing f开发者_C百科ile handles, or probably streams. We eventually get a TooManyOpenFiles exception under very heavy load. Based on the output of lsof, we are pretty sure we know where the leak is (in our logging system), but my question is: how can I write a unit test that checks, when it's complete, that resources have been closed properly? Is there a way to query the JRE to find out how many files are currently open? Can I somehow intercept file operations so I can monitor them?

I suspect I will have to instrument my code in order to manage all the file I/O, count references, and make sure they are getting closed that way, but if anyone knows of a top-down solution akin to those ideas I mentioned above, that would be a huge help!


Since you are talking about Tests, PowerMock http://code.google.com/p/powermock/ might do the trick. It makes it possible to mock static methods and constructors if I am not mistaken. So you could mock/spy on the constructors and on the close methods or what ever you need for freeing the resources.

I try to avoid it in my tests but in the case which you describe it might be worth the hassle.


You can use aspect-oriented programming (AOP) tool like AspectJ to add code to count open/closed files to FileInputStream and FileOutputStream. This is fairly easy to do (details depend on the tool, of course) robust and noninvasive.


Looks like you can watch this via JMX.

Someone posted code here: http://java-monitor.com/forum/showthread.php?t=130

You'll have to enable JMX in your JVM if you haven't already.


You could write your own "library" for the normal IO classes, FileInputStream, etc. That tracks (in test) what caller opened it, if it's still open, a global list, etc. Have it wrap a "real" FileInputStream. Then use that everywhere in your code instead of a "normal" FileInputStream et al.

Then at the end of your unit test you assert WrappedFileInputStreams.assertAllWereClosed or what have you.

Another option would be to write your methods so they accept FileinputStream as a parameter somehow, then call them, then assert your parameter comes out "closed now" after the method ends.

Or if you know you'll be on linux, do a system call to lsof and it should not list any files as location '(deleted)'. https://unix.stackexchange.com/a/64737/8337

For some reason on OS X it's not that easy, it doesn't show "(deleted)" but you could still detect if the file is gone by looping over lsof -p ... and checking if each file is actually there on the file system...

0

精彩评论

暂无评论...
验证码 换一张
取 消