Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Blocker
-
Resolution: Fixed
-
Affects Version/s: JRuby 1.6.3, JRuby 1.6.4
-
Fix Version/s: JRuby 1.6.5, JRuby 1.7.0.pre1
-
Component/s: Embedding
-
Labels:None
-
Environment:Java Version: 1.6.0_27 /Win7 64-bit
-
Number of attachments :0
Description
Hi,
I use the ScriptEngineManager to execute Ruby Scripts from Java Code, but with JRuby 1.6.4 the following code breaks:
for (; ; ) { ScriptEngineManager m = new ScriptEngineManager(); m.getEngineByExtension("rb").eval("puts(\""+new Date()+"\")"); }
The loop stops with no error message after about 20 outputs. If I use the same code with JRuby 1.5.6 everything works fine.
BTW: If I do the Script Engine initialization outside the loop it works (but thats not the way I should have to do it
- no other ScriptEngine implementation has a problem with the kind of initialization shown above).
Add. info from the mailing list:
Thanks for reporting this. I confirmed exactly the same weird behavior
on master, too. This doesn't happen on ScriptingContainer, so is a
JSR223 impl bug probably. I'm going to look into this bug.Would you file this in JIRA? You can track a bug fixing.
-Yoko
Activity
Hi,
thanks for your quick response. I tried the latest version. On about 2 of 10 tries with the same code I get a BufferOverflowException shown below:
java.nio.BufferOverflowException at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:165) at org.jruby.util.io.ChannelStream.bufferedWrite(ChannelStream.java:1054) at org.jruby.util.io.ChannelStream.fwrite(ChannelStream.java:1233) at org.jruby.RubyIO.fwrite(RubyIO.java:1441) at org.jruby.RubyIO.write(RubyIO.java:1323) at org.jruby.RubyIO$i$1$0$write.call(RubyIO$i$1$0$write.gen:65535) at org.jruby.RubyClass.finvoke(RubyClass.java:699) at org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:548) at org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:361) at org.jruby.RubyIO.write(RubyIO.java:2301) at org.jruby.RubyIO.putsArray(RubyIO.java:2290) at org.jruby.RubyIO.puts(RubyIO.java:2256) at org.jruby.RubyKernel.puts(RubyKernel.java:522) at org.jruby.RubyKernel$s$0$0$puts.call(RubyKernel$s$0$0$puts.gen:65535) at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:630) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:207) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169) at org.jruby.ast.FCallOneArgNode.interpret(FCallOneArgNode.java:36) at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104) at org.jruby.ast.RootNode.interpret(RootNode.java:129) at org.jruby.evaluator.ASTInterpreter.INTERPRET_ROOT(ASTInterpreter.java:120) at org.jruby.Ruby.runInterpreter(Ruby.java:720) at org.jruby.Ruby.runInterpreter(Ruby.java:728) at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:119) at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:90) at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:153) at other.ScriptStdout.main(ScriptStdout.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) org.jruby.embed.EvalFailedException: java.nio.BufferOverflowException at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:141) at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:90) at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:153) at other.ScriptStdout.main(ScriptStdout.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: java.nio.BufferOverflowException at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:165) at org.jruby.util.io.ChannelStream.bufferedWrite(ChannelStream.java:1054) at org.jruby.util.io.ChannelStream.fwrite(ChannelStream.java:1233) at org.jruby.RubyIO.fwrite(RubyIO.java:1441) at org.jruby.RubyIO.write(RubyIO.java:1323) at org.jruby.RubyIO$i$1$0$write.call(RubyIO$i$1$0$write.gen:65535) at org.jruby.RubyClass.finvoke(RubyClass.java:699) at org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:548) at org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:361) at org.jruby.RubyIO.write(RubyIO.java:2301) at org.jruby.RubyIO.putsArray(RubyIO.java:2290) at org.jruby.RubyIO.puts(RubyIO.java:2256) at org.jruby.RubyKernel.puts(RubyKernel.java:522) at org.jruby.RubyKernel$s$0$0$puts.call(RubyKernel$s$0$0$puts.gen:65535) at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:630) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:207) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169) at org.jruby.ast.FCallOneArgNode.interpret(FCallOneArgNode.java:36) at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104) at org.jruby.ast.RootNode.interpret(RootNode.java:129) at org.jruby.evaluator.ASTInterpreter.INTERPRET_ROOT(ASTInterpreter.java:120) at org.jruby.Ruby.runInterpreter(Ruby.java:720) at org.jruby.Ruby.runInterpreter(Ruby.java:728) at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:119) ... 8 more
Ouch. I'll look into this problem further.
The culprit of the original problem was that the setting of IO was auto-close. So, I changed that to be no auto-close IO.
You might wonder why you get into this trouble. JRuby engine implements the feature of redirecting standard I/O to user provided I/O. Yes, you don't use this feature, but SimpleScriptContext does that during the initialization. Of course SimpleScriptContext sets System.out/System.err, but there's no way to know whether those are System.out/System.err or use provided ones when SimpleScriptContext comes to engine's implementation. So, in all evaluations, JRubyEngine sets I/O that SimpleScriptContext holds.
Other languages' engines don't implement this feature or have far simple implementations around IO. Ruby is complicated and not Java originated language. This is the reason you accidentally had this problem.
I pushed a supposed fix for this issue in rev. 6bbc25d of jruby-1_6 branch and rev. 92f5770 of master branch.
Would you try it out again?
Sorry for the late response...
I tried the latest build...but the Exception stays the same...
Exception in thread "main" javax.script.ScriptException: java.nio.BufferOverflowException
at org.jruby.embed.jsr223.JRubyEngine.wrapException(JRubyEngine.java:115)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:93)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:153)
at other.ScriptStdout.main(ScriptStdout.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.nio.BufferOverflowException
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:165)
at org.jruby.util.io.ChannelStream.bufferedWrite(ChannelStream.java:1054)
at org.jruby.util.io.ChannelStream.fwrite(ChannelStream.java:1233)
at org.jruby.RubyIO.fwrite(RubyIO.java:1441)
at org.jruby.RubyIO.write(RubyIO.java:1323)
at org.jruby.RubyIO$i$1$0$write.call(RubyIO$i$1$0$write.gen:65535)
at org.jruby.RubyClass.finvoke(RubyClass.java:699)
at org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:548)
at org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:361)
at org.jruby.RubyIO.write(RubyIO.java:2301)
at org.jruby.RubyIO.putsArray(RubyIO.java:2290)
at org.jruby.RubyIO.puts(RubyIO.java:2256)
at org.jruby.RubyKernel.puts(RubyKernel.java:522)
at org.jruby.RubyKernel$s$0$0$puts.call(RubyKernel$s$0$0$puts.gen:65535)
at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:630)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:207)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169)
at org.jruby.ast.FCallOneArgNode.interpret(FCallOneArgNode.java:36)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104)
at org.jruby.ast.RootNode.interpret(RootNode.java:129)
at org.jruby.evaluator.ASTInterpreter.INTERPRET_ROOT(ASTInterpreter.java:120)
at org.jruby.Ruby.runInterpreter(Ruby.java:720)
at org.jruby.Ruby.runInterpreter(Ruby.java:728)
at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:119)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:90)
... 7 more
Ah, the same...
Would you give us the code that raises BufferOverflowException? I've never seen the exception on OS X just for evaluating "puts(\""new Date()"\")". I think just printing out "puts(\""new Date()"\")" doesn't raise exception on your environment, too.
I don't use the code shown above in my scenario thats right, but the evaluation of "puts(\""new Date()"\")" does throw the Exception also. I testet it under linux yesterday - same excpetion there! It doesn't matter what is evaluated in the loop, simply printing "hello world" also causes the BufferOverflowException...
That makes me puzzled.
I tried on both OSX and Ubuntu, but never raised exception. So, something is not the same between my environment and yours.
I used the latest version of JRuby. Would you please fetch the latest code from git://jruby.org/jruby.git and compile it? Just typing "ant clean; ant" will create jruby.jar under lib directory. Then, use this, just compiled jruby.jar to run the code above. Would you not use IDE. Please try it on command-line.
I did as you said (with rev. 4f4bbe5 - command line), but the Excpetion is still there. As I mentioned above it is not allways present (2/10 or so).
BTW: do you think that maybe JRUBY-3679 describes the same issue?
Thanks for trying it on command line.
Would you let me know how did you ran 10 times? One after another? Or at the same time?
Well, I think JRUBY-3679 is a bit different. Exception looks really similar, but the environment is very different. Probably, concurrency got involved in that issue.
Do you think your JVM automatically divided the process to multiple CPUs? and eventually the code ran concurrently?
I tried one after another - so there is no concurrency involved here.
Hhhm I just tried to run the code above with the latest jruby.jar on Win Vista/32bit, Java Version 1.6.0_23-b05 (and 1.6.0_27-b07), and I'm not able to reproduce the exception here.
So it seams to be a OS or a 32/64 bit issue???
Very likely. ![]()
So, your Win7 and linux are on the same machine?
What linux distribution did you use? I got the exception on linux, too.
Thanks for the info.
When I googled with the keywords, "Windows7 java.nio.BufferOverflowException," I got many. At this moment, I'm not sure those happened for the same reason. However, win7 looks like having some problem.
I see.
I'm now thinking about how JSR223 impl can avoid this problem. There should be a way.
When I change the code, I'll add comment here. So, keep watching this issue.
I pushed the change in rev. 0ad4313 on jruby-1_6 and 386b82e on master branches.
Would you try the latest version out?
It looks pretty good. I'm not able to reproduce the exception on win7 and open suse (vm)!!!
thx!!! ![]()
Thanks for confirming.
I added a new class to bypass the problematic area. This fix works as long as a user doesn't use javax.script.SimpleScriptContext. The existence of SimpleBindings/SimpleScriptContext brings a lot of problem to JRuby Engine.
I'm going resolve this issue.
I fixed the bug by a commit of rev. 8f84564 on jruby-1_6 and rc0615e7 on master branches.
If you have a chance, would you try latest one?