Category: Issue Encountered

NIO2 is great… until…

In Java 7, Oracle gave us a shiny new API to do dingy old file-related tasks with less boilerplate code (and with shiny new functionalities like file change listeners, memory mapping, asynchronous I/O, etc.), and in Java 8 Oracle extended the API to use Streams.

I recently discovered that it’s great… until you need to delete a directory on Windows. The odd thing is that I really wasn’t using much NIO code.

I have integration tests where the code under test creates a temporary directory (not using NIO). The code under test test writes a file into that directory (not using NIO). The test used NIO (Files.lines()) to read the generated file and a static file for comparison. The post-test clean-up deletes the contents of the temporary directory and then the temporary directory itself (not using NIO).

Without using NIO to do the deletion, I had only a boolean (the result of File.delete()) to tell me that the directory was not actually deleted. Switching to NIO (Files.delete(), which throws an exception when it fails), I could see that the deletion failed because the directory was supposedly not empty. This might be caused by the never-to-be fixed bug 4715154 in the JDK.

I tried looping with delays and forced garbage collection (as suggested in this StackOverflow comment), but to no avail. When I got rid of NIO in the test code that reads the files for comparison, then the deletion worked. All’s well that ends well, I suppose, and the hour spent debugging that issue was educational.

I thought it was worth writing up a warning about this, though, because when you’re doing TDD you don’t expect to spend an hour debugging code in your @AfterClass method which does nothing but delete a directory and its contents.