JRuby 嵌入问题:Puts 似乎失败并出现 RaiseException:(Errno::EBADF) 错误的文件描述符

发布于 2024-11-27 16:03:22 字数 2288 浏览 3 评论 0原文

我试图在用我自己的 PrintStream 替换默认输出后评估脚本。

ScriptingContainer container = new ScriptingContainer();
container.setOut( my new output target printstream);
container.runScriptlet("puts \"*value*\"";);

无聊的包装器 Stacktrace

    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)

请注意,我的 PrintStream 只是打印到 StringBuilder,然后我在测试中对其进行断言。 PrintStream.checkError() 始终返回 false,并且如果它附加到 StringBuilder,则它永远不会失败。

每个测试都会对 ScriptingContainer 执行以下清理操作。我添加了resetXXX调用只是为了方便,无论有没有它们,问题仍然存在。

final ScriptingContainer container = ...
            container.resetWriter();
            container.resetErrorWriter();
            container.terminate();

更新 看起来单独运行测试一切正常,但是使用 put 运行测试又失败了,因为有些东西被搞砸了。奇怪的是,鉴于我正在重置编写器并终止容器,为什么它会被搞砸。当我在测试之间拆掉 Jruby 时,还有什么我需要删除的吗?

I am attempting to eval a script after replacing hte default out with my own PrintStream.

ScriptingContainer container = new ScriptingContainer();
container.setOut( my new output target printstream);
container.runScriptlet("puts \"*value*\"";);

Boring wrapper Stacktrace

    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)

Interesting wrapped exception

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)

Note my PrintStream simply prints to a StringBuilder which i then assert against in the test. The PrintStream.checkError() always returns false and given it appends to a StringBuilder it never fails.

Each test does cleanup doing the following to the ScriptingContainer. I added the resetXXX calls just to be nice and the problem persists with or without them.

final ScriptingContainer container = ...
            container.resetWriter();
            container.resetErrorWriter();
            container.terminate();

Update
It would appear that running the test alone, everything works, but running the test with puts after another fails because something is screwed. THe strange thing is why is it screwed given i am resetting the writers and terminating the container. Is there anything else i need to kill when i tear down Jruby between tests ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

失眠症患者 2024-12-04 16:03:23

看来我的测试没有关闭我的 ScriptingContainer。愚蠢的错误。也就是说 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();
    }
}

}

It would appear my tests were not shutting down my ScriptingContainer. Dumb bug. That said ScriptingContainer.resetWriter() and ScriptingContainer.resetError() dont really work.

public class 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();
    }
}

}

遗忘曾经 2024-12-04 16:03:23

这对我有用(JRuby 1.6.2,Java 1.6.0):

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*\"");
    }
}

This works for me (JRuby 1.6.2, Java 1.6.0):

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*\"");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文