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

Inconsistent java method/signature choosing depending on java version/platform

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.7
    • Fix Version/s: JRuby 1.7.0.pre2
    • Component/s: Java Integration
    • Labels:
      None
    • Number of attachments :
      1

      Description

      On Windows it picks .submit(Runnable):

      Z:\ssl>jruby --version
      jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (Java HotSpot(TM) Client VM 1.7.0_04) [Windows Server 2008 R2-x86-java]
      
      Z:\ssl>jruby method_choosing_bug.rb
      opening connection to example.com...
      opened
      <- "GET / HTTP/1.1\r\nAccept: */*\r\nHost: example.com\r\n\r\n"
      Conn close because of error can't convert nil into String
      TypeError: can't convert nil into String
                  concat at org/jruby/RubyString.java:2485
               rbuf_fill at method_choosing_bug.rb:12
               readuntil at c:/jruby-1.6.7/lib/ruby/1.8/net/protocol.rb:116
                readline at c:/jruby-1.6.7/lib/ruby/1.8/net/protocol.rb:126
        read_status_line at c:/jruby-1.6.7/lib/ruby/1.8/net/http.rb:2026
                read_new at c:/jruby-1.6.7/lib/ruby/1.8/net/http.rb:2015
                 request at c:/jruby-1.6.7/lib/ruby/1.8/net/http.rb:1051
                __file__ at method_choosing_bug.rb:23
                   start at c:/jruby-1.6.7/lib/ruby/1.8/net/http.rb:543
                  (root) at method_choosing_bug.rb:23
      

      On Linux it's .submit(Callable):

      $ jruby --version
      jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (OpenJDK 64-Bit Server VM 1.6.0_23) [linux-amd64-java]
      $ jruby method_choosing_bug.rb 
      opening connection to example.com...
      opened
      <- "GET / HTTP/1.1\r\nAccept: */*\r\nHost: example.com\r\n\r\n"
      -> "HTTP/1.0 302 Found\r\n"
      -> "Location: http://www.iana.org/domains/example/\r\n"
      -> "Server: BigIP\r\n"
      -> "Connection: Keep-Alive\r\n"
      -> "Content-Length: 0\r\n"
      -> "\r\n"
      reading 0 bytes...
      -> ""
      read 0 bytes
      Conn keep-alive
      #<Net::HTTPFound 302 Found readbody=true>
      

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        Well, there's a bit of an issue here...which one is the "right" one to call? They're both equally valid, since all we have to go on is that you have a block of code you want to pass to submit. They're being chosen differently on different systems because they're coming out of JDK's reflection logic in different orders, and they both "match".

        One way to get around this would be to use a small explicit implementation of the interface you see, like this:

        class RunnableProc
        include java.lang.Runnable
        def initialize(&block)
        @block = block
        end
        def run; block.call; end
        end
        ...
        executor.submit(RunnableProc.new

        { block body }

        )

        There may be a way to disambiguate these calls without using a concrete class, too. I need to poke around a bit.

        Show
        Charles Oliver Nutter added a comment - Well, there's a bit of an issue here...which one is the "right" one to call? They're both equally valid, since all we have to go on is that you have a block of code you want to pass to submit. They're being chosen differently on different systems because they're coming out of JDK's reflection logic in different orders, and they both "match". One way to get around this would be to use a small explicit implementation of the interface you see, like this: class RunnableProc include java.lang.Runnable def initialize(&block) @block = block end def run; block.call; end end ... executor.submit(RunnableProc.new { block body } ) There may be a way to disambiguate these calls without using a concrete class, too. I need to poke around a bit.
        Hide
        zaadjis added a comment -

        If it's not possible on all platforms to always pick the same method, maybe an exception should be raised or a warning should be written to STDERR?

        After I figured out what was going on (was reading the wiki), I ended up using java_method:

        submit_method = executor.java_method :submit, [Java::JavaLang::Class.for_name 'java.util.concurrent.Callable']
        callable_future = submit_method.call { block body }
        
        Show
        zaadjis added a comment - If it's not possible on all platforms to always pick the same method, maybe an exception should be raised or a warning should be written to STDERR? After I figured out what was going on (was reading the wiki ), I ended up using java_method : submit_method = executor.java_method :submit, [Java::JavaLang::Class.for_name 'java.util.concurrent.Callable'] callable_future = submit_method.call { block body }
        Hide
        Charles Oliver Nutter added a comment -

        In other method selection cases we do show a warning, but the path that turns objects into interface implementations does not. I'll look into that a bit.

        Show
        Charles Oliver Nutter added a comment - In other method selection cases we do show a warning, but the path that turns objects into interface implementations does not. I'll look into that a bit.
        Hide
        Charles Oliver Nutter added a comment -

        We can't really "fix" this issue, since there's no way to disambiguate disjoint methods, but I have added warning output when we're forced to "just pick one".

        Here's what the output looks like for your script:

        system ~/projects/jruby $ jruby -X-C tmp/method_choosing_bug.rb 
        opening connection to example.com...
        opened
        <- "GET / HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: example.com\r\n\r\n"
        tmp/method_choosing_bug.rb:11 warning: ambiguous Java methods found, using submit(java.lang.Runnable)
        Conn close because of error can't convert nil into String
        TypeError: can't convert nil into String
        ...
        

        And the commit to master:

        commit f38b8e5a353873c91bf71869108502d0a3adeff1
        Author: Charles Oliver Nutter <headius@headius.com>
        Date:   Tue Jul 3 15:49:45 2012 -0500
        
            Kinda sorta fix JRUBY-6674
            
            Inconsistent java method/signature choosing depending on java version/platform
            
            There's no mechanism we can use to choose between disjoint methods
            but we don't want to hard error out for backward compat and
            because often disjointedness is because of multiple numeric
            overloads. Instead, we warn when we have to choose from multiple
            and show the name and signature we chose. This should only show up
            once per call site per unique set of argument types, but it will
            help diagnose improper dispatches.
        
        :100644 100644 41f3dd1... 4d5c921... M	src/org/jruby/java/dispatch/CallableSelector.java
        :100644 100644 2850d20... 8c69b16... M	src/org/jruby/java/invokers/RubyToJavaInvoker.java
        :100644 100644 6a56d82... efced1c... M	src/org/jruby/javasupport/Java.java
        :100644 100644 6f9effa... 99c6dfa... M	src/org/jruby/javasupport/JavaAccessibleObject.java
        :100644 100644 b27fc00... c0f35df... M	src/org/jruby/javasupport/JavaConstructor.java
        :100644 100644 575f1a2... 7ad39cd... M	src/org/jruby/javasupport/JavaField.java
        :100644 100644 3084e6c... aefe6e6... M	src/org/jruby/javasupport/JavaMethod.java
        :100644 100644 9bc611e... d1fb2c1... M	test/org/jruby/javasupport/test/TestNativeException.java
        
        Show
        Charles Oliver Nutter added a comment - We can't really "fix" this issue, since there's no way to disambiguate disjoint methods, but I have added warning output when we're forced to "just pick one". Here's what the output looks like for your script: system ~/projects/jruby $ jruby -X-C tmp/method_choosing_bug.rb opening connection to example.com... opened <- "GET / HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: example.com\r\n\r\n" tmp/method_choosing_bug.rb:11 warning: ambiguous Java methods found, using submit(java.lang.Runnable) Conn close because of error can't convert nil into String TypeError: can't convert nil into String ... And the commit to master: commit f38b8e5a353873c91bf71869108502d0a3adeff1 Author: Charles Oliver Nutter <headius@headius.com> Date: Tue Jul 3 15:49:45 2012 -0500 Kinda sorta fix JRUBY-6674 Inconsistent java method/signature choosing depending on java version/platform There's no mechanism we can use to choose between disjoint methods but we don't want to hard error out for backward compat and because often disjointedness is because of multiple numeric overloads. Instead, we warn when we have to choose from multiple and show the name and signature we chose. This should only show up once per call site per unique set of argument types, but it will help diagnose improper dispatches. :100644 100644 41f3dd1... 4d5c921... M src/org/jruby/java/dispatch/CallableSelector.java :100644 100644 2850d20... 8c69b16... M src/org/jruby/java/invokers/RubyToJavaInvoker.java :100644 100644 6a56d82... efced1c... M src/org/jruby/javasupport/Java.java :100644 100644 6f9effa... 99c6dfa... M src/org/jruby/javasupport/JavaAccessibleObject.java :100644 100644 b27fc00... c0f35df... M src/org/jruby/javasupport/JavaConstructor.java :100644 100644 575f1a2... 7ad39cd... M src/org/jruby/javasupport/JavaField.java :100644 100644 3084e6c... aefe6e6... M src/org/jruby/javasupport/JavaMethod.java :100644 100644 9bc611e... d1fb2c1... M test/org/jruby/javasupport/test/TestNativeException.java

          People

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

            Dates

            • Created:
              Updated:
              Resolved: