我试图在用我自己的PrintStream替换hte default out之后评估一个脚本。
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();
更新 似乎单独运行测试,一切正常,但是使用puts之后运行测试会因为某些事情被搞砸而失败。奇怪的是,由于我正在重置编写器并终止容器,为什么它会被搞砸。当我在测试之间拆除Jruby时还有什么需要杀死的吗?
答案 0 :(得分:1)
看来我的测试没有关闭我的ScriptingContainer。笨蛋。那说ScriptingContainer.resetWriter()和ScriptingContainer.resetError()确实不起作用。
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();
}
}
}
答案 1 :(得分:0)
这对我有用(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*\"");
}
}