JRuby

Java class with initialize() method can't be constructed from jruby

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: JRuby 0.9.0, JRuby 0.9.1, JRuby 0.9.2, JRuby 0.9.8, JRuby 0.9.9, JRuby 1.0.0RC1, JRuby 1.0.0RC2, JRuby 1.0.0RC3
  • Fix Version/s: JRuby 1.0.1, JRuby 1.1b1
  • Component/s: Java Integration
  • Labels:
    None
  • Environment:
    SVN Trunk of jRuby on Linux, Sun JDK 1.5.0.07
  • Testcase included:
    yes
  • Number of attachments :
    2

Description

Attached test case testClassWithInitialize.rb with attached java class org.jruby.javasupport.test.TestClassWithInitialize fails with the following:

test/testClassWithInitialize.rb:8:in `invoke': invokee not a java object (TypeError)
from ruby/testClassWithInitialize.rb:8:in `initialize'
from ruby/testClassWithInitialize.rb:8:in `new'
from ruby/testClassWithInitialize.rb:8

Name collision with ruby initialize()?

Issue Links

Activity

Hide
Thomas E Enebo added a comment -

Yep. It is a collision with the initialize used by the Ruby class we use to create a proxy to the included Java class. We actually knew about this, but for some reason did not have a bug open on it.

Show
Thomas E Enebo added a comment - Yep. It is a collision with the initialize used by the Ruby class we use to create a proxy to the included Java class. We actually knew about this, but for some reason did not have a bug open on it.
Hide
Charles Oliver Nutter added a comment -

This may be fixed along with Bill's fixes for JRUBY-778.

Show
Charles Oliver Nutter added a comment - This may be fixed along with Bill's fixes for JRUBY-778.
Hide
Charles Oliver Nutter added a comment -

This is a tricky one. I'm not sure what the right way to fix this is. Probably the simplest way is to provide a special name for Java methods like initialize that can't be overridden. I know that makes it a bit more cumbersome to invoke them, but it would be much more painful internally to try to allow an "initialize" method to come through.

So suggestions?

_initialize?
_initialize_?
__initialize__?
j_initialize?
send(:initialize)? (maybe with a custom impl of send that is aware of such things?)
Show
Charles Oliver Nutter added a comment - This is a tricky one. I'm not sure what the right way to fix this is. Probably the simplest way is to provide a special name for Java methods like initialize that can't be overridden. I know that makes it a bit more cumbersome to invoke them, but it would be much more painful internally to try to allow an "initialize" method to come through. So suggestions?
_initialize?
_initialize_?
__initialize__?
j_initialize?
send(:initialize)? (maybe with a custom impl of send that is aware of such things?)
Hide
Charles Oliver Nutter added a comment -

The patch for JRUBY-814 may make this easier to fix, but doesn't currently resolve this issue.

Show
Charles Oliver Nutter added a comment - The patch for JRUBY-814 may make this easier to fix, but doesn't currently resolve this issue.
Hide
Ola Bini added a comment -

I propose either
"initialize!"

or following the Java convention, and taking the class name.

Show
Ola Bini added a comment - I propose either "initialize!" or following the Java convention, and taking the class name.
Hide
Charles Oliver Nutter added a comment -

Not going to get fixed in time for 099. Needs more debate and discussion.

Show
Charles Oliver Nutter added a comment - Not going to get fixed in time for 099. Needs more debate and discussion.
Hide
Charles Oliver Nutter added a comment -

I'm starting to think we should leave the built-in initialize alone. It's generally been the case that Java stuff entering Ruby is a second-class citizen when it comes to conflicting with critical method names, and initialize certainly falls into that category. So I think providing something like initialize! which is impossible to define in Java code would be a pretty good choice. Plus, it seems like it almost fits what an exclamation point means, since initialize! could reasonably be expected to initialize the target Java object (service, cache, whatever it is).

Show
Charles Oliver Nutter added a comment - I'm starting to think we should leave the built-in initialize alone. It's generally been the case that Java stuff entering Ruby is a second-class citizen when it comes to conflicting with critical method names, and initialize certainly falls into that category. So I think providing something like initialize! which is impossible to define in Java code would be a pretty good choice. Plus, it seems like it almost fits what an exclamation point means, since initialize! could reasonably be expected to initialize the target Java object (service, cache, whatever it is).
Hide
Bill Dortch added a comment -

I was also thinking about using the exclamation point for overriding protected methods (and fields), should we decide to support that capability. If we want to make them protected methods in Ruby (thus preserving at least some semblance of their "protectedness"), we'll need to name them differently from public methods, as there are many instances in the java.* packages of public and protected methods overloading the same name (see java.awt.Component, for example).

I don't think that precludes using ! for other purposes.

Show
Bill Dortch added a comment - I was also thinking about using the exclamation point for overriding protected methods (and fields), should we decide to support that capability. If we want to make them protected methods in Ruby (thus preserving at least some semblance of their "protectedness"), we'll need to name them differently from public methods, as there are many instances in the java.* packages of public and protected methods overloading the same name (see java.awt.Component, for example). I don't think that precludes using ! for other purposes.
Hide
Charles Oliver Nutter added a comment -

I like initialize! myself, but this isn't going to get done by tomorrow. We really oughta have this for for 1.0, so I'll increase to critical.

Show
Charles Oliver Nutter added a comment - I like initialize! myself, but this isn't going to get done by tomorrow. We really oughta have this for for 1.0, so I'll increase to critical.
Hide
Charles Oliver Nutter added a comment -

I think this may need to get punted for 1.0. Perhaps there's a workaround we can add to this bug? I'm not going to have time to work on it...but if someone else has a patch, it could be accepted today.

Show
Charles Oliver Nutter added a comment - I think this may need to get punted for 1.0. Perhaps there's a workaround we can add to this bug? I'm not going to have time to work on it...but if someone else has a patch, it could be accepted today.
Hide
Bill Dortch added a comment -

This issue isn't quite what it was when it was opened. A Java class with an initialize method can be instantiated, and that class can call it's initialize method. We just ignore the method in JRuby, so you can't call it or override it:

public class TestInit {

    public TestInit() {
        initialize();
    }
    public void initialize() {
        System.out.println("initialize called");
    }
}
irb(main):001:0> include Java
=> Object
irb(main):002:0> T = org.jruby.javasupport.TestInit
=> Java::OrgJrubyJavasupport::TestInit
irb(main):003:0> t = T.new
initialize called
=> #<Java::OrgJrubyJavasupport::TestInit:0x1e1ec86 @java_object=org.jruby.javasupport.TestInit@10418
76>
irb(main):004:0> class T2 < T
irb(main):005:1> def initialize(*args)
irb(main):006:2> super
irb(main):007:2> puts "T2 init"
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> t2 = T2.new
initialize called
T2 init
=> #<T2:0x148e798 @java_object=org.jruby.javasupport.TestInit$Proxy0@135605a>
irb(main):011:0> t.class
=> Java::OrgJrubyJavasupport::TestInit
irb(main):012:0>

So I think this is a (comparatively) minor issue right now...

Show
Bill Dortch added a comment - This issue isn't quite what it was when it was opened. A Java class with an initialize method can be instantiated, and that class can call it's initialize method. We just ignore the method in JRuby, so you can't call it or override it:
public class TestInit {

    public TestInit() {
        initialize();
    }
    public void initialize() {
        System.out.println("initialize called");
    }
}
irb(main):001:0> include Java
=> Object
irb(main):002:0> T = org.jruby.javasupport.TestInit
=> Java::OrgJrubyJavasupport::TestInit
irb(main):003:0> t = T.new
initialize called
=> #<Java::OrgJrubyJavasupport::TestInit:0x1e1ec86 @java_object=org.jruby.javasupport.TestInit@10418
76>
irb(main):004:0> class T2 < T
irb(main):005:1> def initialize(*args)
irb(main):006:2> super
irb(main):007:2> puts "T2 init"
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> t2 = T2.new
initialize called
T2 init
=> #<T2:0x148e798 @java_object=org.jruby.javasupport.TestInit$Proxy0@135605a>
irb(main):011:0> t.class
=> Java::OrgJrubyJavasupport::TestInit
irb(main):012:0>
So I think this is a (comparatively) minor issue right now...
Hide
Charles Oliver Nutter added a comment -

Do we have a good way to do a "java_send" on java objects? That woudl be a sufficient workaround for now.

public class TestInit {

    public TestInit() {
        initialize();
    }
    public void initialize() {
        System.out.println("initialize called");
    }
}
t =TestInit.new
t.java_send :initialize

etc...

Show
Charles Oliver Nutter added a comment - Do we have a good way to do a "java_send" on java objects? That woudl be a sufficient workaround for now.
public class TestInit {

    public TestInit() {
        initialize();
    }
    public void initialize() {
        System.out.println("initialize called");
    }
}
t =TestInit.new
t.java_send :initialize
etc...
Hide
Charles Oliver Nutter added a comment -

Either this has a nice workaround like java_send or it's going to remain "broken" for 1.0...not enough time for a more major addition to Java support.

Show
Charles Oliver Nutter added a comment - Either this has a nice workaround like java_send or it's going to remain "broken" for 1.0...not enough time for a more major addition to Java support.
Hide
Bill Dortch added a comment -

There's not an easy workaround now. I could hack something together, but then we'd have to live with it. I'd rather wait and do this post-1.0 as part of the work to be done to support protected methods/fields (which I thought I was going to get done as part of JRUBY-814, but just ran into too many gotchas).

The post-1.0 work will involve (at least) a reworking of the JavaClass code, which will be a good thing (there's still room for improvement in performance, etc.), and we might want to stop and look at the whole Java support infrastructure – there's a lot I'd do differently in a perfect world...

Meanwhile, as I noted, I don't think this issue is quite as serious now as when the problem was initially reported – the submitted test case now works.

-Bill

Show
Bill Dortch added a comment - There's not an easy workaround now. I could hack something together, but then we'd have to live with it. I'd rather wait and do this post-1.0 as part of the work to be done to support protected methods/fields (which I thought I was going to get done as part of JRUBY-814, but just ran into too many gotchas). The post-1.0 work will involve (at least) a reworking of the JavaClass code, which will be a good thing (there's still room for improvement in performance, etc.), and we might want to stop and look at the whole Java support infrastructure – there's a lot I'd do differently in a perfect world... Meanwhile, as I noted, I don't think this issue is quite as serious now as when the problem was initially reported – the submitted test case now works. -Bill
Hide
Charles Oliver Nutter added a comment -

Since the original case works, I'm marking this as fixed. There's a large overhaul of java integration coming, so the remaining discussions should be addressed as part of that.

Show
Charles Oliver Nutter added a comment - Since the original case works, I'm marking this as fixed. There's a large overhaul of java integration coming, so the remaining discussions should be addressed as part of that.
Hide
Charles Oliver Nutter added a comment - - edited

Updating an old bug that gets hit for "jruby java initialize"...

The ultimate solution for this, as of JRuby 1.4, is to use the java_send and java_alias methods.

obj.java_send :initialize

class ClassOfObj; java_alias :jinitialize, :initialize; end

Show
Charles Oliver Nutter added a comment - - edited Updating an old bug that gets hit for "jruby java initialize"... The ultimate solution for this, as of JRuby 1.4, is to use the java_send and java_alias methods. obj.java_send :initialize class ClassOfObj; java_alias :jinitialize, :initialize; end

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: