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

Objects loaded via Marshal don't get Java class applied corrected unless passed through fn taking exact type

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.5.3
    • Fix Version/s: JRuby 1.7.0.pre1
    • Component/s: Java Integration
    • Labels:
      None
    • Environment:
      Solaris, Sun JVM
    • Number of attachments :
      1

      Description

      Download and run the test case.

      The output is

      classViaCreating, class = org.jruby.RubyObject
      functionTakingObject, class = ImplementingClass_476069089
      functionTakingObject, class = ImplementingClass_476069089

      I would expect it to be

      classViaCreating, class = ImplementingClass2_476069293
      functionTakingObject, class = ImplementingClass_476069089
      functionTakingObject, class = ImplementingClass_476069089

      Uncommenting a line which passses another object of that type of a Java function expecting the exact type in testcase2.rb will change those lines to the expected output.

      Using a similar function which just takes an Object won't change it.

        Activity

        Hide
        Ben Summers added a comment - - edited

        -

        Show
        Ben Summers added a comment - - edited -
        Hide
        Nick Sieger added a comment -

        When a Ruby object is returned from a Java interface method, it is casted to the return type, even though in this case the Ruby class is made to implement the interface. So when the return type is Object JRuby essentially does nothing.

        This might be a bug, but it's hard to tell. The Ruby object hasn't been converted to a Java object before so the JRuby internals aren't noticing that it can or should be converted to a Java object/interface implementation.

        Show
        Nick Sieger added a comment - When a Ruby object is returned from a Java interface method, it is casted to the return type, even though in this case the Ruby class is made to implement the interface. So when the return type is Object JRuby essentially does nothing. This might be a bug, but it's hard to tell. The Ruby object hasn't been converted to a Java object before so the JRuby internals aren't noticing that it can or should be converted to a Java object/interface implementation.
        Hide
        Ben Summers added a comment -

        The class has been declared to implement that interface, so I would have expected the instance to implement it, regardless of the signature of the method which was called.

        It's a problem for my application because it has a method which returns 'anything', which could be stuff like java.lang.Number or classes implemented in Ruby. The Java side then makes sense of it and does the right thing.

        Different Java classes are returned depending on what code has run before, which made it amusing to track down.

        I have worked around this by calling a Java function which expects an object of the right type just after the base class is defined, and this has resolved the issue.

        Show
        Ben Summers added a comment - The class has been declared to implement that interface, so I would have expected the instance to implement it, regardless of the signature of the method which was called. It's a problem for my application because it has a method which returns 'anything', which could be stuff like java.lang.Number or classes implemented in Ruby. The Java side then makes sense of it and does the right thing. Different Java classes are returned depending on what code has run before, which made it amusing to track down. I have worked around this by calling a Java function which expects an object of the right type just after the base class is defined, and this has resolved the issue.
        Hide
        Ben Summers added a comment -

        Also, if you don't run the object through Marshal, it works as I would expect.

        There's different behaviour when you create the object through Klass.new and via Marshal.load(), which can't be right?

        Show
        Ben Summers added a comment - Also, if you don't run the object through Marshal, it works as I would expect. There's different behaviour when you create the object through Klass.new and via Marshal.load(), which can't be right?
        Hide
        Ben Summers added a comment -

        Checked it in master, still fails.

        $ jruby -v
        jruby 1.6.0.dev (ruby 1.8.7 patchlevel 330) (2011-01-06 16aa9c5) (Java HotSpot(TM) Client VM 1.6.0_22) [SunOS-x86-java]
        $ ./run.sh
        classViaCreating, class = org.jruby.RubyObject
        functionTakingObject, class = ImplementingClass_277712892
        functionTakingObject, class = ImplementingClass_277712892

        Show
        Ben Summers added a comment - Checked it in master, still fails. $ jruby -v jruby 1.6.0.dev (ruby 1.8.7 patchlevel 330) (2011-01-06 16aa9c5) (Java HotSpot(TM) Client VM 1.6.0_22) [SunOS-x86-java] $ ./run.sh classViaCreating, class = org.jruby.RubyObject functionTakingObject, class = ImplementingClass_277712892 functionTakingObject, class = ImplementingClass_277712892
        Hide
        Charles Oliver Nutter added a comment -

        I think this is a simple matter of forcing unmarshaling to trigger any delayed JI class setup. I'll poke around.

        Show
        Charles Oliver Nutter added a comment - I think this is a simple matter of forcing unmarshaling to trigger any delayed JI class setup. I'll poke around.
        Hide
        Charles Oliver Nutter added a comment -

        I'm only fixing this in 1.7, since it's somewhat old and the change is more invasive than I'd like for 1.6.x.

        Here's the commit. I need a JI spec, and more testing would be most welcome.

        commit 284ab7dc07b09623e63acdaaa2b1b397c1a86b15
        Author: Charles Oliver Nutter <headius@headius.com>
        Date:   Mon Jan 9 13:35:13 2012 -0600
        
            Fix JRUBY-5317.
            
            Objects loaded via Marshal don't get Java class applied corrected unless passed through fn taking exact type
            
            The problem here was that Marshal uses allocate to create objects
            coming in, but all our logic for initializing JI-related subclasses
            lived in "new". By moving that logic to allocate we clean up both
            the "new" stuff (no need for custom method anymore) and also ensure
            the logic runs regardless of whether you "new" or "allocate" the
            object.
            
            I have run our tests, but it would be helpful to get more cases
            surrounding Marshal and have user codebases run with this patch
            in place.
        
        Show
        Charles Oliver Nutter added a comment - I'm only fixing this in 1.7, since it's somewhat old and the change is more invasive than I'd like for 1.6.x. Here's the commit. I need a JI spec, and more testing would be most welcome. commit 284ab7dc07b09623e63acdaaa2b1b397c1a86b15 Author: Charles Oliver Nutter <headius@headius.com> Date: Mon Jan 9 13:35:13 2012 -0600 Fix JRUBY-5317. Objects loaded via Marshal don't get Java class applied corrected unless passed through fn taking exact type The problem here was that Marshal uses allocate to create objects coming in, but all our logic for initializing JI-related subclasses lived in "new". By moving that logic to allocate we clean up both the "new" stuff (no need for custom method anymore) and also ensure the logic runs regardless of whether you "new" or "allocate" the object. I have run our tests, but it would be helpful to get more cases surrounding Marshal and have user codebases run with this patch in place.

          People

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

            Dates

            • Created:
              Updated:
              Resolved: