ScriptingContainer Output Redirection Not Working

Hi,

It appears that ScriptingContainer.setWriter() is not working. I’ve
Googled this and it was supposed to have been fixed quite a while back
but some users have still been experiencing problems. If you search
“redirect” on this forum, there appears to be an unresolved post.

Here is some sample code:

// JRuby
jRubyContainer = new
ScriptingContainer(LocalContextScope.THREADSAFE,
LocalVariableBehavior.PERSISTENT);

// Output interceptor
outputInterceptor = new OutputInterceptor(id, outputQueue);
jRubyContainer.setWriter(outputInterceptor);

OutputInterceptor extends java.io.Writer. If I execute a script
involving stdout:

puts “Hello, World!”

The output appears on stdout and never makes it to my writer.

FWIW, I’m using JRuby 1.6.7. I’ve tried both jruby-complete and
jruby.jar.

Any suggestions for a workaround?

Thank you :slight_smile:

Hello,

On Thu, Feb 23, 2012 at 1:03 PM, Bart T. [email protected] wrote:

jRubyContainer = new
puts “Hello, World!”

The output appears on stdout and never makes it to my writer.

Writer type object is converted to InputStream type object internally.
This is because JRuby wants InputStream type to print something out.

Output redirection works at least for StringWriter. My guess is
OutputInterceptor overrides methods in the way embedding API doesn’t
expect. You might find the reason if you look at the code,
org.jruby.embed.io.WriterOutputStream.java .

-Yoko

Yoko H. wrote in post #1048500:

Writer type object is converted to InputStream type object internally.
This is because JRuby wants InputStream type to print something out.

Output redirection works at least for StringWriter. My guess is
OutputInterceptor overrides methods in the way embedding API doesn’t
expect. You might find the reason if you look at the code,
org.jruby.embed.io.WriterOutputStream.java .

Thanks for the response, Yoko. I’m a bit confused by this. I thought all
of these classes are ultimately derived from Writer. I’ve overridden all
Writer methods and don’t see any of them being called.

I did try using a StringWriter, and it does work (although for my
purposes, I need to be able to intercept things as they are sent to the
output without buffering). Perhaps this is more of a Java question
rather than something JRuby-specific but I’m hoping someone can point me
in the right direction.

Actually, I discovered something interesting: I have to call setWriter()
immediately before runScriptlet, otherwise the setting is lost. The
culprit seems to be:

Ruby jRubyRuntime = jRubyContainer.getProvider().getRuntime();

I obtain the runtime immediately before I execute any JRuby code.
Because I need to peek at the internal state, I need to have access to
the runtime. Initially, I had obtained a reference to both the
ScriptingContainer and Ruby runtime within the constructor of my wrapper
class, but I noticed that the Ruby runtime would not be valid after
executing some code (and I didn’t quite understand why). I’m going to
dig through JRuby in more detail tomorrow but I assume that on each
evaluation, a new runtime object is created (which would explain why my
Writer was being overwritten)?