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

NoMethodError calling callMethod on instance of reopened Java class

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.7, JRuby 1.7.0.pre1
    • Fix Version/s: JRuby 1.7.0.pre2
    • Component/s: Java Integration
    • Labels:
      None
    • Environment:
      OS X 10.7.4 + Apple Java 1.6.0_33-b03-424-11M3720
      Android 2.3 and 4.0
    • Number of attachments :
      2

      Description

      This is causing us to use runScriptlet in the Ruboto internals, but the behavior is the same using OS X + Apple Java 6.

      We reopen a Java class to define Ruby methods on it, and then call these methods directly from Java. Here is an example:

      import org.jruby.embed.ScriptingContainer;
      
      class ReopenJavaClass {
          public ReopenJavaClass() {}
      
          public static void main(String[] args) throws Exception {
              ScriptingContainer sc = new ScriptingContainer(org.jruby.embed.LocalContextScope.SINGLETON,
                      org.jruby.embed.LocalVariableBehavior.TRANSIENT);
              sc.put("ReopenJavaClass", sc.runScriptlet("Java::ReopenJavaClass"));
              sc.runScriptlet("class ReopenJavaClass ; def ruby_method ; puts 'Success!' ; end ; end");
              sc.callMethod(new ReopenJavaClass(), "ruby_method");
          }
      }
      

      When we run this we get the following exception:

      $ javac -cp .:../jruby/dist/jruby-complete-1.7.0.preview2.dev.jar -d tmp ReopenJavaClass.java 
      $ java -cp .:../jruby/dist/jruby-complete-1.7.0.preview2.dev.jar ReopenJavaClass
      NoMethodError: undefined method `ruby_method' for main:Object
      Exception in thread "main" org.jruby.embed.InvokeFailedException: (NoMethodError) undefined method `ruby_method' for main:Object
      	at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.call(EmbedRubyObjectAdapterImpl.java:296)
      	at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.callMethod(EmbedRubyObjectAdapterImpl.java:241)
      	at org.jruby.embed.ScriptingContainer.callMethod(ScriptingContainer.java:1367)
      	at ReopenJavaClass.main(ReopenJavaClass.java:11)
      Caused by: org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `ruby_method' for main:Object
      

      Are we using callMethods wrongly? Any help on this would be absolutely great!

        Activity

        Hide
        Uwe Kubosch added a comment -

        OK, Yoko, I merged the code since you agreed to the functional change. I am confident that it is good.

        Show
        Uwe Kubosch added a comment - OK, Yoko, I merged the code since you agreed to the functional change. I am confident that it is good.
        Hide
        Yoko Harada added a comment -

        Uwe, I have a objection about this change.

        You changed the feature of API, which will confuse users.

        When people evaluate "def my_method; end" only, a return value will be null. Released versions don't require users to change receiver to container.getTopSelf(). Please don't change test as much as possible.

        I'll fix those.

        Show
        Yoko Harada added a comment - Uwe, I have a objection about this change. You changed the feature of API, which will confuse users. When people evaluate "def my_method; end" only, a return value will be null. Released versions don't require users to change receiver to container.getTopSelf(). Please don't change test as much as possible. I'll fix those.
        Hide
        Uwe Kubosch added a comment -

        Yoko added a new method runRubyMethod with the new behavior. It is good!

        I think I will widen the version of runRubyMethod to allow for return type and block so we cover the most general case. This version can be used for the more simple cases as well, and we can add convenience versions later if we want.

        Show
        Uwe Kubosch added a comment - Yoko added a new method runRubyMethod with the new behavior. It is good! I think I will widen the version of runRubyMethod to allow for return type and block so we cover the most general case. This version can be used for the more simple cases as well, and we can add convenience versions later if we want.
        Hide
        Uwe Kubosch added a comment -

        I'll add a version of runRubyMethod without Block for easier use with reflection since all signature classes except Block are in the standard Java library.

        Show
        Uwe Kubosch added a comment - I'll add a version of runRubyMethod without Block for easier use with reflection since all signature classes except Block are in the standard Java library.
        Hide
        Uwe Kubosch added a comment -

        The new runRubyMethod method solves this nicely.

        Show
        Uwe Kubosch added a comment - The new runRubyMethod method solves this nicely.

          People

          • Assignee:
            Yoko Harada
            Reporter:
            Uwe Kubosch
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: