Java JRuby嵌入prob:Puts似乎因RaiseException:(Errno::EBADF)错误的文件描述符而失败

Java JRuby嵌入prob:Puts似乎因RaiseException:(Errno::EBADF)错误的文件描述符而失败,java,jruby,Java,Jruby,在用我自己的PrintStream替换默认值之后,我正在尝试评估脚本 ScriptingContainer container = new ScriptingContainer(); container.setOut( my new output target printstream); container.runScriptlet("puts \"*value*\"";); 钻孔包装堆栈跟踪 at org.eclipse.jdt.internal.junit.runner.Remot

在用我自己的PrintStream替换默认值之后,我正在尝试评估脚本

ScriptingContainer container = new ScriptingContainer();
container.setOut( my new output target printstream);
container.runScriptlet("puts \"*value*\"";);
钻孔包装堆栈跟踪

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.jruby.exceptions.RaiseException: (Errno::EBADF) Bad file descriptor
org.jruby.embed.EvalFailedException: (Errno::EBADF) Bad file descriptor
    at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:127)
    at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1231)
    at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1224)
    ... my boring test case stuff
    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 junit.framework.TestCase.runTest(TestCase.java:168)
    at junit.framework.TestCase.runBare(TestCase.java:134)
有趣的包装异常

org.jruby.exceptions.RaiseException: (Errno::EBADF) Bad file descriptor
    at org.jruby.RubyIO.write(org/jruby/RubyIO.java:1319)
    at org.jruby.RubyIO.write(org/jruby/RubyIO.java:2297)
    at org.jruby.RubyIO.puts(org/jruby/RubyIO.java:2252)
    at org.jruby.RubyKernel.puts(org/jruby/RubyKernel.java:522)
    at #<Class:0x101e4f266>.(root)(<script>:1)
更新 看起来,单独运行测试,一切都正常,但是运行一个接一个的测试失败了,因为有些事情搞砸了。奇怪的是,既然我正在重置写入程序并终止容器,为什么它会出错。当我在测试之间拆掉Jruby时,还有什么我需要杀死的吗?

这对我来说很有用(Jruby 1.6.2,Java 1.6.0):


我的测试似乎没有关闭脚本容器。哑巴虫。也就是说ScriptingContainer.resetWriter()和ScriptingContainer.resetError()实际上不起作用

公共类JRubyShellPutsProblem{

public static void main(String[] args) {
    final StringBuilder b = new StringBuilder();

    for (int i = 0; i < 3; i++) {
        final ScriptingContainer container = new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.PERSISTENT);
        final PrintStream printStream = PrintStreams.printer(Printers.stringBuilder(b), LineEnding.CR, Charset.defaultCharset());
        container.setOutput(printStream);
        container.setError(printStream); // yes same as out, still works.
        container.runScriptlet("puts \"hello" + i + "\"\n");
        printStream.flush();
        System.out.println(b.toString());

        // container.resetWriter(); <-- blows up 
        // container.resetErrorWriter();
        container.terminate();
    }
}
publicstaticvoidmain(字符串[]args){
最终StringBuilder b=新StringBuilder();
对于(int i=0;i<3;i++){
final ScriptingContainer=new ScriptingContainer(LocalContextScope.CONCURRENT,LocalVariableBehavior.PERSISTENT);
final PrintStream PrintStream=PrintStreams.printer(Printers.stringBuilder(b)、LineEnding.CR、Charset.defaultCharset());
container.setOutput(打印流);
container.setError(printStream);//是与out相同,仍然有效。
runScriptlet(“放置\“hello”+i+“\”\n”);
printStream.flush();
System.out.println(b.toString());

//container.resetWriter();哪一行引发了异常?您能显示您的printstream实例化吗?另外,我认为setOut()不存在-我假设它是一个拼写错误。是的setOut是一个拼写错误,它应该是ScriptingContainer.setOutput():)我的PrintStream非常基本,我覆盖了所有方法,只调用了一个类似的StringBuilder.append方法。例外当然是write方法,但它们也能正常工作。无论哪种方式,我的PrintStream都不会抛出,因此即使输出“丢失”JRuby永远不会知道它只是调用我的printstream并假设它工作。我不知道它是如何抱怨的,为什么抱怨的。嗨,Rob thanx回答,我更新了我的q以包含堆栈转储。尝试将它放在一个循环中,并将传递给ScriptingContainer的作用域更改为LocalContextScope.CONCURRENT,&LocalVariableBehavior.PERSISTENT。
import org.jruby.embed.*;

class HelloWorldApp {
    public static void main(String[] args) {
        ScriptingContainer container = new ScriptingContainer();
        try{
            container.setOutput(new java.io.PrintStream("log.txt"));
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
        container.runScriptlet("puts \"*value*\"");
    }
}
public static void main(String[] args) {
    final StringBuilder b = new StringBuilder();

    for (int i = 0; i < 3; i++) {
        final ScriptingContainer container = new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.PERSISTENT);
        final PrintStream printStream = PrintStreams.printer(Printers.stringBuilder(b), LineEnding.CR, Charset.defaultCharset());
        container.setOutput(printStream);
        container.setError(printStream); // yes same as out, still works.
        container.runScriptlet("puts \"hello" + i + "\"\n");
        printStream.flush();
        System.out.println(b.toString());

        // container.resetWriter(); <-- blows up 
        // container.resetErrorWriter();
        container.terminate();
    }
}