Today I was investigating Bug 427148. The problem is when you update on Windows it sometimes fails if the executable is being updated. This is because the file is locked, and you cannot overwrite it with a new version. The exciting part is that sometimes it works! In fact, we’ve had very little luck finding someone who can reliably reproduce the problem.
After working with a number of contributors on the bug report, I started to notice a pattern. All the error logs that were posted included absolute paths that started with D:\. Then the Eureka moment! When p2 updates your system, it first backs-up (moves) all the files it needs to update. It moves the files into a temp directory usually on C:\. If moving fails, it performs a copy & delete. Of course this works fine, except for the executable which is currently locked by the OS.
On windows, moving across volumes is tricky:
renameTo public boolean renameTo(File dest) Renames the file denoted by this abstract pathname. Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
But this documentation is not entirely correct. It indicates that if a ‚move‘ (rename) was not successful, then a false should be returned. But checkout the following example.
In this case, I tried to rename the eclipse.exe to a different volume. After the move, both the new and old file exists! I would argue that the rename failed. It appears that Java is using the copy & delete strategy here too, but since the executable cannot be deleted, it leaves both (and happy returns true). If you really want to test that a renamed worked, you need to test both the result of the rename and check again that the original file is no longer present.
What do they say about Java? Write once, debug everywhere 🙂