History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: JRUBY-1735
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Bill Dortch
Reporter: Ola Bini
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
JRuby

Java Integration wraps to much

Created: 17/Dec/07 02:32 PM   Updated: Monday 06:44 PM
Component/s: Java Integration
Affects Version/s: None
Fix Version/s: JRuby 1.1.4

Time Tracking:
Not Specified

Issue Links:
Duplicate
 


 Description  « Hide
With a class like this:
package org;

public class Passer {
    public Runnable pass(Runnable obj) {
        return obj;
    }
}

Note the use of Runnable.
This will fail:

require 'java'

class MyRunnable
  include java.lang.Runnable
  
  def run
    puts "running"
  end
  
  def foobar
    puts "foobar"
  end
end


r = MyRunnable.new

r.run
r.foobar

x = org.Passer.new.pass(r)

p x == r

x.run
x.foobar

Since our Java Integration wraps the object even though there's no need to.



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Ola Bini - 17/Dec/07 03:05 PM
This was worse than I imagined.

The argument is converted. The instanceof RubyObject is NOT a Runnable - instead, it's got a proxy inside of it that is unwrapped for the Java method call, and then rewrapped on the way out. The problem is that the rewrapping is really all over the place, so there is no obvious place to keep the association between what goes in and what goes out. But this is really a critical issue - I would imagine that everything that goes in through Java Integration would come out in the same way, not be a totally new thing that doesn't have the same class, the same methods, the same instance variables.

This is seriously broken and needs to be fixed. I'm sad to say the fix would be too large for 1.1. At least in my opinion.

Bill?


Bill Dortch - 17/Dec/07 03:06 PM
Same as JRUBY-199, JRUBY-1513. The problem is that the previous proxy is not picked up when the object is returned from Java (the problem is in the unwrapping when we pass an object out to Java, as well as the re-wrapping when it is returned).

I tried a fix a few weeks ago that stored non-primitive (or primitive wrapper) types in a map on the way out, and reunited them on the way back. The problem was that the map (a standard WeakHashMap) called equals() to compare objects, which sometimes caused objects to be mated with the wrong proxies. Will try again with a map that compares using ==. I'll have a couple of extra days over the holidays, will get to it then.

-Bill


Bill Dortch - 17/Dec/07 03:22 PM
BTW (just saw Ola's message), the re-wrapping happens in Java.new_instance_for, so there is a single point to catch that. I don't have access to my code right now (on my other computer), but there is also a single point to catch objects on the way out. My fix also gets rid of the JavaObject cache, which serves no purpose.

Charles Oliver Nutter - 12/May/08 05:15 PM
Where do we stand on this one, gents?

Thomas E Enebo - 25/Aug/08 06:44 PM
Fixed by recent JI work. Test case now runs as expected.