Thanks for the info Uwe. I know the unlock is to be used as a last resort, and if you know no one else has a reference to the lock. The fact that on Windows this fails is perfect, that's exactly what I want - for unlock() to fail if someone keeps a reference to the lock. On Unix - I didn't realize that's what happens, so that's indeed broken.
I'm not sure that the fix is just javadocs ... perhaps the fix should be to add an unlock() method to Lock and impl it in SimpleFSLock by calling release(), but on NativeFSLock to first obtain the lock and if that succeeds, release it. That way, the obtain would fail and we can throw an exception. Also, we can keep release() and impl in NativeFSLock to first obtain if it does not hold the lock.
Also, what you say about IndexWriter.unlock() should be used if SimpleFSLockFactory is used, and only then, is not: (1) documented anywhere and (2) reasonable. What if I implement a Lock over a DB (I think someone even posted something about that a while ago). I should still be able to call unlock().
The thing is, IMO unlock() should throw an exception if it failed, and currently it does so in SimpleFSLock but not for NativeFSLock. The symmetry is broken, and I see no reason why it shouldn't fail for NativeFSLock, so the application knows about it. Notice that NativeFSLock fails to thrown an exception only because makeLock creates a new instance with the 'lock' member being null. It gives a false impression that the unlock succeeded, and for the wrong reason.