created a file "t.txt"
ruby code: File.new('t.txt').flock(File::LOCK_EX)
for C Ruby, it works well.
it will throw java.nio.channels.NonWritableChannelException on JRuby.
the following is the full stacktrace I got:
----start---
C:\Documents and Settings\xli\Desktop\New Folder\jruby-1.0>bin\jruby -e "p File.new('t.txt').flock(F
ile::LOCK_EX)"
FileChannelImpl.java :773:in `sun.nio.ch.FileChannelImpl.lock': java.nio.channels.NonWritableChannelE
xception: null (NativeException)
from FileChannel.java:865:in `java.nio.channels.FileChannel.lock'
from RubyFile.java :314:in `org.jruby.RubyFile.flock'
from null:-1:in `org.jruby.RubyFileInvokerflock1.call'
from FastInvocationCallback.java:49:in `org.jruby.runtime.callback.FastInvocationCallback.ex
ecute'
from SimpleCallbackMethod.java:81:in `org.jruby.internal.runtime.methods.SimpleCallbackMetho
d.call'
from EvaluationState.java:568:in `org.jruby.evaluator.EvaluationState.callNode'
from EvaluationState.java:207:in `org.jruby.evaluator.EvaluationState.evalInternal'
from EvaluationState.java:2190:in `org.jruby.evaluator.EvaluationState.setupArgs'
... 8 levels...
from Main.java:173:in `org.jruby.Main.runInterpreter'
from Main.java:120:in `org.jruby.Main.run'
from Main.java:95:in `org.jruby.Main.main'
Complete Java stackTrace
java.nio.channels.NonWritableChannelException
at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:773)
at java.nio.channels.FileChannel.lock(FileChannel.java:865)
at org.jruby.RubyFile.flock(RubyFile.java:314)
at org.jruby.RubyFileInvokerflock1.call (Unknown Source)
at org.jruby.runtime.callback.FastInvocationCallback.execute(FastInvocationCallback.java:49)
at org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java :81
)
at org.jruby.evaluator.EvaluationState.callNode(EvaluationState.java:568)
at org.jruby.evaluator.EvaluationState.evalInternal(EvaluationState.java:207)
at org.jruby.evaluator.EvaluationState.setupArgs (EvaluationState.java:2190)
at org.jruby.evaluator.EvaluationState.fCallNode(EvaluationState.java:1007)
at org.jruby.evaluator.EvaluationState.evalInternal(EvaluationState.java:253)
at org.jruby.evaluator.EvaluationState.rootNode (EvaluationState.java:1609)
at org.jruby.evaluator.EvaluationState.evalInternal(EvaluationState.java:356)
at org.jruby.evaluator.EvaluationState.eval(EvaluationState.java:164)
at org.jruby.Ruby.eval (Ruby.java:287)
at org.jruby.Ruby.compileOrFallbackAndRun(Ruby.java:315)
at org.jruby.Main.runInterpreter(Main.java:228)
at org.jruby.Main.runInterpreter(Main.java:173)
at org.jruby.Main.run (Main.java:120)
at org.jruby.Main.main(Main.java:95)
--end--
I took a look at JRuby code org.jruby.RubyFile and org.jruby.util.IOHandler,
and there is only one IOHandler sub class(IOHandlerSeekable) I found implements getChannel method for RubyFile to use it to lock file.
IOHandlerSeekable will create a RandomAccessFile and get FileChannel from it in the method getChannel.
And it pass file open mode to initialize RandomAccessFile object.
FileChannel will throw NonWritableChannelException when it trys to lock a file with shared is false and it was not opened for writing.
so, the code "File.new("t.txt", "w+").flock(File::LOCK_EX)" works well.
this is the test associated with the bug.
and the patch to fix it.
Running the full test suite on jruby worked okay with the patch, and indeed if ruby is waiting to have the file opened read/write by default, we might as well do it in jruby.