Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.5
    • Fix Version/s: JRuby 1.6.6
    • Component/s: None
    • Labels:
      None
    • Environment:
      MacOS X 10.7
      java version "1.6.0_26"
      Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
      Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
    • Number of attachments :
      0

      Description

      When running code like this:

      require "open3"
      
      output, status = Open3.capture2e("date")
      

      in an IRB session in 1.9 mode, I get this output:

      jruby-1.6.5 :001 > require "open3"
       => true 
      jruby-1.6.5 :002 > output, status = Open3.capture2e("date")
      Sat Dec 10 09:58:39 PST 2011
      Java::JavaLang::RuntimeException: CallBlock does not have a static scope; this should not be called
      	from org.jruby.runtime.CallBlock.getStaticScope(CallBlock.java:107)
      	from org.jruby.RubyProc.setup(RubyProc.java:159)
      	from org.jruby.RubyProc.newProc(RubyProc.java:118)
      	from org.jruby.RubyProc.newProc(RubyProc.java:113)
      	from org.jruby.Ruby.newProc(Ruby.java:2919)
      	from org.jruby.internal.runtime.RubyRunnable.<init>(RubyRunnable.java:60)
      	from org.jruby.RubyThread.initialize(RubyThread.java:269)
      	from org.jruby.RubyThread$i$0$0$initialize.call(RubyThread$i$0$0$initialize.gen:65535)
      	from org.jruby.RubyClass.finvoke(RubyClass.java:557)
      	from org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:541)
      	from org.jruby.RubyObject.callInit(RubyObject.java:233)
      	from org.jruby.RubyThread.startThread(RubyThread.java:313)
      	from org.jruby.RubyThread.newInstance(RubyThread.java:230)
      	from org.jruby.RubyProcess.detach(RubyProcess.java:923)
      	from org.jruby.RubyProcess$s$1$0$detach.call(RubyProcess$s$1$0$detach.gen:65535)
      	from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
      ... 160 levels...
      	from org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
      	from org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:190)
      	from org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:179)
      	from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
      	from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169)
      	from Users.tomdz.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_5.bin.irb.__file__(/Users/tomdz/.rvm/rubies/jruby-1.6.5/bin/irb:17)
      	from Users.tomdz.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_5.bin.irb.load(/Users/tomdz/.rvm/rubies/jruby-1.6.5/bin/irb)
      	from org.jruby.Ruby.runScript(Ruby.java:693)
      	from org.jruby.Ruby.runScript(Ruby.java:686)
      	from org.jruby.Ruby.runNormally(Ruby.java:593)
      	from org.jruby.Ruby.runFromMain(Ruby.java:442)
      	from org.jruby.Main.doRunFromMain(Main.java:321)
      	from org.jruby.Main.internalRun(Main.java:241)
      	from org.jruby.Main.run(Main.java:207)
      	from org.jruby.Main.run(Main.java:191)
      	from org.jruby.Main.main(Main.java:171)
      

      Notice also how the command produces output on stdout even though capture2e is supposed to capture that output.

        Activity

        Hide
        Hiro Asari added a comment -

        Confirmed on master.

        Show
        Hiro Asari added a comment - Confirmed on master.
        Hiro Asari made changes -
        Field Original Value New Value
        Description When running code like this:

        {code:ruby}
        require "open3"

        output, status = Open3.capture2e("date")
        {code}

        in an IRB session in 1.9 mode, I get this output:

        jruby-1.6.5 :001 > require "open3"
         => true
        jruby-1.6.5 :002 > output, status = Open3.capture2e("date")
        Sat Dec 10 09:58:39 PST 2011
        Java::JavaLang::RuntimeException: CallBlock does not have a static scope; this should not be called
        from org.jruby.runtime.CallBlock.getStaticScope(CallBlock.java:107)
        from org.jruby.RubyProc.setup(RubyProc.java:159)
        from org.jruby.RubyProc.newProc(RubyProc.java:118)
        from org.jruby.RubyProc.newProc(RubyProc.java:113)
        from org.jruby.Ruby.newProc(Ruby.java:2919)
        from org.jruby.internal.runtime.RubyRunnable.<init>(RubyRunnable.java:60)
        from org.jruby.RubyThread.initialize(RubyThread.java:269)
        from org.jruby.RubyThread$i$0$0$initialize.call(RubyThread$i$0$0$initialize.gen:65535)
        from org.jruby.RubyClass.finvoke(RubyClass.java:557)
        from org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:541)
        from org.jruby.RubyObject.callInit(RubyObject.java:233)
        from org.jruby.RubyThread.startThread(RubyThread.java:313)
        from org.jruby.RubyThread.newInstance(RubyThread.java:230)
        from org.jruby.RubyProcess.detach(RubyProcess.java:923)
        from org.jruby.RubyProcess$s$1$0$detach.call(RubyProcess$s$1$0$detach.gen:65535)
        from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
        ... 160 levels...
        from org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
        from org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:190)
        from org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:179)
        from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
        from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169)
        from Users.tomdz.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_5.bin.irb.__file__(/Users/tomdz/.rvm/rubies/jruby-1.6.5/bin/irb:17)
        from Users.tomdz.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_5.bin.irb.load(/Users/tomdz/.rvm/rubies/jruby-1.6.5/bin/irb)
        from org.jruby.Ruby.runScript(Ruby.java:693)
        from org.jruby.Ruby.runScript(Ruby.java:686)
        from org.jruby.Ruby.runNormally(Ruby.java:593)
        from org.jruby.Ruby.runFromMain(Ruby.java:442)
        from org.jruby.Main.doRunFromMain(Main.java:321)
        from org.jruby.Main.internalRun(Main.java:241)
        from org.jruby.Main.run(Main.java:207)
        from org.jruby.Main.run(Main.java:191)
        from org.jruby.Main.main(Main.java:171)

        Notice also how the command produces output on stdout even though capture2e is supposed to capture that output.
        When running code like this:

        {code}
        require "open3"

        output, status = Open3.capture2e("date")
        {code}

        in an IRB session in 1.9 mode, I get this output:

        {noformat}
        jruby-1.6.5 :001 > require "open3"
         => true
        jruby-1.6.5 :002 > output, status = Open3.capture2e("date")
        Sat Dec 10 09:58:39 PST 2011
        Java::JavaLang::RuntimeException: CallBlock does not have a static scope; this should not be called
        from org.jruby.runtime.CallBlock.getStaticScope(CallBlock.java:107)
        from org.jruby.RubyProc.setup(RubyProc.java:159)
        from org.jruby.RubyProc.newProc(RubyProc.java:118)
        from org.jruby.RubyProc.newProc(RubyProc.java:113)
        from org.jruby.Ruby.newProc(Ruby.java:2919)
        from org.jruby.internal.runtime.RubyRunnable.<init>(RubyRunnable.java:60)
        from org.jruby.RubyThread.initialize(RubyThread.java:269)
        from org.jruby.RubyThread$i$0$0$initialize.call(RubyThread$i$0$0$initialize.gen:65535)
        from org.jruby.RubyClass.finvoke(RubyClass.java:557)
        from org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:541)
        from org.jruby.RubyObject.callInit(RubyObject.java:233)
        from org.jruby.RubyThread.startThread(RubyThread.java:313)
        from org.jruby.RubyThread.newInstance(RubyThread.java:230)
        from org.jruby.RubyProcess.detach(RubyProcess.java:923)
        from org.jruby.RubyProcess$s$1$0$detach.call(RubyProcess$s$1$0$detach.gen:65535)
        from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
        ... 160 levels...
        from org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
        from org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:190)
        from org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:179)
        from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
        from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169)
        from Users.tomdz.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_5.bin.irb.__file__(/Users/tomdz/.rvm/rubies/jruby-1.6.5/bin/irb:17)
        from Users.tomdz.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_5.bin.irb.load(/Users/tomdz/.rvm/rubies/jruby-1.6.5/bin/irb)
        from org.jruby.Ruby.runScript(Ruby.java:693)
        from org.jruby.Ruby.runScript(Ruby.java:686)
        from org.jruby.Ruby.runNormally(Ruby.java:593)
        from org.jruby.Ruby.runFromMain(Ruby.java:442)
        from org.jruby.Main.doRunFromMain(Main.java:321)
        from org.jruby.Main.internalRun(Main.java:241)
        from org.jruby.Main.run(Main.java:207)
        from org.jruby.Main.run(Main.java:191)
        from org.jruby.Main.main(Main.java:171)
        {noformat}

        Notice also how the command produces output on stdout even though capture2e is supposed to capture that output.
        Hide
        Charles Oliver Nutter added a comment -

        This is actually a simple problem to find, but I'm not sure of the best fix.

        Process.detach returns a thread. It is implemented using a CallBlock and a pure-Java closure body. Proc, when getting set up as a thread, attempts to access the static scope of the block so it can ensure it won't share the lastline/backref scope where the thread's closure was created. Since CallBlock does not provide a static scope, it blows up here.

        There are a couple ways we could fix it:

        • Special case the logic in RubyProc to avoid attempting to get a static scope from a CallBlock
        • Modify CallBlock to always return a dummy static scope

        I'll explore the latter, since it seems a bit cleaner.

        Show
        Charles Oliver Nutter added a comment - This is actually a simple problem to find, but I'm not sure of the best fix. Process.detach returns a thread. It is implemented using a CallBlock and a pure-Java closure body. Proc, when getting set up as a thread, attempts to access the static scope of the block so it can ensure it won't share the lastline/backref scope where the thread's closure was created. Since CallBlock does not provide a static scope, it blows up here. There are a couple ways we could fix it: Special case the logic in RubyProc to avoid attempting to get a static scope from a CallBlock Modify CallBlock to always return a dummy static scope I'll explore the latter, since it seems a bit cleaner.
        Hide
        Charles Oliver Nutter added a comment -

        I have committed a partial fix that eliminates the exception, but capture2e doesn't actually work right yet for a couple reasons:

        • We do not support stream redirection yet in any IO options relating to process management. This is partially because the JDK does not make such things easy to do; we'll have to emulate it on Java 6. On Java 7, we can use better facilities for process launching that do support redirection, but that code is not present yet.
        • The JDK classes do their own waiting on the child process, which causes our wait to fail spuriously (only one "waitpid" can succeed). As a result, Process.detach (used by open3) can sometimes fail to produce the expected result.

        We'll need to look into both issues to really call this one fixed, since I've simply masked the primary failure and exposed secondary ones.

        commit 36d3e03bd254f1006f5d1dff6de3a406bbadb6d4
        Author: Charles Oliver Nutter <headius@headius.com>
        Date:   Mon Jan 9 02:44:43 2012 -0600
        
            Modify StaticScope factories to provide a dummy scope for unscoped constructs.
        
        Show
        Charles Oliver Nutter added a comment - I have committed a partial fix that eliminates the exception, but capture2e doesn't actually work right yet for a couple reasons: We do not support stream redirection yet in any IO options relating to process management. This is partially because the JDK does not make such things easy to do; we'll have to emulate it on Java 6. On Java 7, we can use better facilities for process launching that do support redirection, but that code is not present yet. The JDK classes do their own waiting on the child process, which causes our wait to fail spuriously (only one "waitpid" can succeed). As a result, Process.detach (used by open3) can sometimes fail to produce the expected result. We'll need to look into both issues to really call this one fixed, since I've simply masked the primary failure and exposed secondary ones. commit 36d3e03bd254f1006f5d1dff6de3a406bbadb6d4 Author: Charles Oliver Nutter <headius@headius.com> Date: Mon Jan 9 02:44:43 2012 -0600 Modify StaticScope factories to provide a dummy scope for unscoped constructs.
        Hide
        Charles Oliver Nutter added a comment -

        Reported issue is fixed; we know Open3 and popen still need work.

        Show
        Charles Oliver Nutter added a comment - Reported issue is fixed; we know Open3 and popen still need work.
        Charles Oliver Nutter made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Assignee Thomas E Enebo [ enebo ] Charles Oliver Nutter [ headius ]
        Fix Version/s JRuby 1.6.6 [ 18033 ]
        Resolution Fixed [ 1 ]
        Charles Oliver Nutter made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Thomas Dudziak
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: