简体   繁体   中英

JRuby Embedding prob: Puts appears to fails with RaiseException: (Errno::EBADF) Bad file descriptor

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 ?

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

}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM