Skip to content

Low-level Java error printed on Errno::EPIPE exception #5003

@janko

Description

@janko

Environment

$ jruby -v
jruby 9.1.15.0 (2.3.3) 2017-12-07 929fde8 Java HotSpot(TM) 64-Bit Server VM 25.40-b25 on 1.8.0_40-b27 +jit [darwin-x86_64]
$ uname -a
Darwin Jankos-MacBook-Pro-2.local 17.3.0 Darwin Kernel Version 17.3.0: Thu Nov  9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 x86_64

Expected Behavior

When writing to a broken pipe using IO.copy_stream, I expect Errno::EPIPE exception to be raised without anything else printed, as it is the case on MRI:

require "stringio"

read_pipe, write_pipe = IO.pipe
read_pipe.close

IO.copy_stream(StringIO.new("foo"), write_pipe)
script.rb:6:in `write': Broken pipe (Errno::EPIPE)
        from script.rb:6:in `copy_stream'
        from script.rb:6:in `<main>'

Actual Behavior

On JRuby, in addition to the Errno::EPIPE exception, we get a java.io.IOException: Broken pipe internal exception also printed out:

java.io.IOException: Broken pipe
        at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
        at sun.nio.ch.FileDispatcherImpl.write(FileDispatcherImpl.java:60)
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
        at sun.nio.ch.IOUtil.write(IOUtil.java:65)
        at sun.nio.ch.SinkChannelImpl.write(SinkChannelImpl.java:167)
        at org.jruby.RubyIO.transfer(RubyIO.java:4323)
        at org.jruby.RubyIO.copy_stream(RubyIO.java:4205)
        at org.jruby.RubyIO$INVOKER$s$0$2$copy_stream.call(RubyIO$INVOKER$s$0$2$copy_stream.gen)
        at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:725)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:338)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183)
        at script.invokeOther6:copy_stream(script.rb:6)
        at script.RUBY$script(script.rb:6)
        at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:625)
        at org.jruby.ir.Compiler$1.load(Compiler.java:95)
        at org.jruby.Ruby.runScript(Ruby.java:831)
        at org.jruby.Ruby.runNormally(Ruby.java:750)
        at org.jruby.Ruby.runNormally(Ruby.java:768)
        at org.jruby.Ruby.runFromMain(Ruby.java:581)
        at org.jruby.Main.doRunFromMain(Main.java:417)
        at org.jruby.Main.internalRun(Main.java:305)
        at org.jruby.Main.run(Main.java:232)
        at org.jruby.Main.main(Main.java:204)
Errno::EPIPE: Broken pipe - Broken pipe
  copy_stream at org/jruby/RubyIO.java:4224
       <main> at script.rb:6

Note that the behaviour is still the same, an Errno::EPIPE exception is still raised, but in addition to that java.io.IOException: Broken pipe stack trace is displayed, even when I rescue Errno::EPIPE. The thing is that in my case I'm expecting that Errno::EPIPE will be raised in certain scenarios, so this internal Java stack trace is something that I would prefer wasn't there, because no exception was actually raised.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions