JRuby Встраивание, проблема: Puts, кажется, терпит неудачу с RaiseException: (Errno :: EBADF) Плохой дескриптор файла - PullRequest
2 голосов
/ 31 июля 2011

Я пытаюсь проверить сценарий после замены hte default по умолчанию своим собственным 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();

Обновление Может показаться, что при запуске теста в одиночку все работает, но при запуске тестас путами за другим не получается, потому что что-то прикручено.Странная вещь - почему это ввернуто, учитывая, что я перезагружаю писателей и завершаю контейнер.Есть ли что-то еще, что мне нужно убить, когда я срываю Джруби между тестами?

Ответы [ 2 ]

1 голос
/ 02 августа 2011

Похоже, мои тесты не закрывали мой 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();
    }
}

}

0 голосов
/ 01 августа 2011

Это работает для меня (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*\"");
    }
}
...