JRuby (please use github issues at http://bugs.jruby.org)
  1. JRuby (please use github issues at http://bugs.jruby.org)
  2. JRUBY-5294

Closure conversion doesn't play nice with some interface method names

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Incomplete
    • Affects Version/s: JRuby 1.5.6
    • Fix Version/s: None
    • Component/s: Java Integration
    • Labels:
      None
    • Environment:
      Mac OS X 10.6.5
      Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
      Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)
      JRuby 1.5.6
    • Number of attachments :
      3

      Description

      Define a Java interface with a single-argument method named 'exec'. Define a Java class that defines a method that uses instances of that interface as a callback. Use JRuby to invoke the class's method using a block as its argument, attempting to take advantage of the closure conversion feature of JRuby.

      When the callback is invoked by the Java method, rather than running the code defined in the block, the system attempts to coerce the argument to a String and Kernel.exec it. The same issue happens for any Kernel.* method name I've tried.

      I'm a complete Ruby/JRuby noob, but based on a quick perusal of the code, it looks like closure conversion is implemented by defining method_missing on a fresh new RubyClass, and that any methods already defined for Ruby's Object are going to be invoked ahead of any interface methods with the same names. This behavior may be completely expected, then; if so, I apologize for the trouble.

      I've attached example code illustrating the problem.

      1. jruby_exec_method_problem.tar.gz
        0.6 kB
        Jason Fager
      2. output_broken.log
        1 kB
        Richard Nienaber
      3. output_works.log
        0.5 kB
        Richard Nienaber

        Activity

        Hide
        Jason Fager added a comment -

        Just for the sake of completeness, a corner case that comes to mind is recursive invocation - if I know that the interface method I'm trying to implement through conversion is named 'exec', within the body of the closure I may try to call 'exec' expecting recursive dispatch back to the closure. Since the Proc's private exec method is visible at that point, though, wouldn't it be invoked instead?

        If the original issue was so rare, I can't imagine that this scenario would crop up often (if ever), and even independent of the original issue, respecting visibility sounds like the right thing to do anyways. +1, thanks again for taking a look.

        Show
        Jason Fager added a comment - Just for the sake of completeness, a corner case that comes to mind is recursive invocation - if I know that the interface method I'm trying to implement through conversion is named 'exec', within the body of the closure I may try to call 'exec' expecting recursive dispatch back to the closure. Since the Proc's private exec method is visible at that point, though, wouldn't it be invoked instead? If the original issue was so rare, I can't imagine that this scenario would crop up often (if ever), and even independent of the original issue, respecting visibility sounds like the right thing to do anyways. +1, thanks again for taking a look.
        Hide
        Charles Oliver Nutter added a comment -

        Bump to 1.6.1 for further consideration. Still tricky, since needs better error or default case, but noncritical (i.e. not much will visibly change for most users with a fix).

        Show
        Charles Oliver Nutter added a comment - Bump to 1.6.1 for further consideration. Still tricky, since needs better error or default case, but noncritical (i.e. not much will visibly change for most users with a fix).
        Hide
        Jeremy Stephens added a comment -

        I ran into this bug today while working on SWT when trying to implement OpenWindowListener (http://help.eclipse.org/indigo/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/OpenWindowListener.html). The Kernel#open method is being called instead.

        I'm working around it by creating an anonymous Ruby class.

        Show
        Jeremy Stephens added a comment - I ran into this bug today while working on SWT when trying to implement OpenWindowListener ( http://help.eclipse.org/indigo/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/OpenWindowListener.html ). The Kernel#open method is being called instead. I'm working around it by creating an anonymous Ruby class.
        Hide
        Richard Nienaber added a comment -

        For the 'work.rb' test case, it works for JRuby 1.7.18 and JRuby HEAD (c1be61a). For 'broken.rb' test case, it still fails. I've attached the output.log for the working and broken test case.

        Show
        Richard Nienaber added a comment - For the 'work.rb' test case, it works for JRuby 1.7.18 and JRuby HEAD (c1be61a). For 'broken.rb' test case, it still fails. I've attached the output.log for the working and broken test case.
        Hide
        Richard Nienaber added a comment -
        Show
        Richard Nienaber added a comment - Moved to https://github.com/jruby/jruby/issues/2392 .

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Jason Fager
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: