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

Instantiation of Ruby subclass of Java class does incorrect constructor argument check

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Not A Bug
    • Affects Version/s: JRuby 1.1.1
    • Fix Version/s: JRuby 1.6.3
    • Component/s: Java Integration
    • Labels:
      None
    • Environment:
      N/A
    • Number of attachments :
      2

      Description

      This bug refers to the case where a Ruby class subclasses a Java class.

      There seems to be a requirement that the Java superclass have a constructor that takes the same number of arguments as the Ruby subclass' initialize method. (Instead, it should do the check against the subclass' call to super.) This impairs the programmer's ability to design subclass constructors' signatures according to their function.

      Definition of Terms for text below:
      J=Java superclass
      R=Ruby subclass of J

      From the JRuby library source, it looks as if concrete.rb is inspecting the arguments of the wrong call. It's inspecting R's initialize's arguments. I would think it should be looking at the arguments to R's call to super (if any) in that initialize method.

      The source file concrete.rb can be found at:

      http://www.koders.com/ruby/fid4571FA39650B617F2D4BD486117CB76A32CE000A.aspx?s=cdef%3Aproxy#L1
      or
      http://snipurl.com/261tg

      ...or in your JRuby installation at /lib/ruby/site_ruby/1.8/builtin/javasupport/proxy/concrete.rb.

      This is elaborated in the attached java-properties-viewer.rb file. In the PropertiesTableModel class' initialize, it would be preferable to have it accept a properties object as a parameter, so that the table model would be general enough to accept any java.util.Properties object. However, because of the bug, this cannot be done in the constructor, because AbstractTableModel does not have a 1-arg constructor.

      In some cases, there is no problem, but that is only by coincidence, since the number of arguments in the subclass' initialize method happens to be matched by a constructor of the Java superclass.

      There is some more information in the attached file. In some cases, I've provided two constructor methods:

      initialize_preferred_but_that_doesnt_work
      initialize

      ... and refactored the code common to both out into the function:

      initialize_common

      1. java-properties-viewer.rb
        4 kB
        Keith R. Bennett
      2. TestRubySubclassing.java
        1.0 kB
        Jonathan Shore

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        The problem here is that the Ruby initialize isn't really used as the constructor for the new Java object type. It's only used to initialize the Ruby side of things. What actually happens when you extend a Java class is that we define a special "new" that calls both the Ruby initialize and the Java <init> constructor separately, then combining them into the ruby/java object pair. So there's technically no way for you to override the construction of the Java object with a different number of arguments.

        This code has been ported into Java recently for 1.1.4, which should make it easier to adjust how this process works. I'm not sure how best to resolve this since we've technically got two class hierarchies' initializers to call.

        Show
        Charles Oliver Nutter added a comment - The problem here is that the Ruby initialize isn't really used as the constructor for the new Java object type. It's only used to initialize the Ruby side of things. What actually happens when you extend a Java class is that we define a special "new" that calls both the Ruby initialize and the Java <init> constructor separately, then combining them into the ruby/java object pair. So there's technically no way for you to override the construction of the Java object with a different number of arguments. This code has been ported into Java recently for 1.1.4, which should make it easier to adjust how this process works. I'm not sure how best to resolve this since we've technically got two class hierarchies' initializers to call.
        Hide
        Matthew King added a comment -

        One (only mildly ugly) workaround is to define self.new for the Ruby class.

        Show
        Matthew King added a comment - One (only mildly ugly) workaround is to define self.new for the Ruby class.
        Hide
        Jonathan Shore added a comment -

        This bug just bit me as well. Unfortunately I need to be able to add more arguments than present in the java superclass to the ruby class ctor.

        What is the issue with tricking out super to call the ctor on the java object? I am aware that in java super must be invoked before any other code in the ctor, though may not be a restriction in the JVM . Can you explain the impediment, may have some ideas on how can adjust.

        Writing a self.new is not very appealing as a permanent fixture.

        Thanks

        Show
        Jonathan Shore added a comment - This bug just bit me as well. Unfortunately I need to be able to add more arguments than present in the java superclass to the ruby class ctor. What is the issue with tricking out super to call the ctor on the java object? I am aware that in java super must be invoked before any other code in the ctor, though may not be a restriction in the JVM . Can you explain the impediment, may have some ideas on how can adjust. Writing a self.new is not very appealing as a permanent fixture. Thanks
        Hide
        Jonathan Shore added a comment -

        I cannot get the self.new workaround to work. Can someone provide pointers. The following test throws a null pointer exception. See attachment

        Show
        Jonathan Shore added a comment - I cannot get the self.new workaround to work. Can someone provide pointers. The following test throws a null pointer exception. See attachment
        Hide
        Jonathan Shore added a comment -

        This test uses self.new, but throws NPE.

        Show
        Jonathan Shore added a comment - This test uses self.new, but throws NPE.
        Hide
        Roger Pack added a comment -

        I think this is fixed now, AFAICT.

        jruby 1.6.1 (ruby-1.8.7-p330) (2011-05-19 5790d31) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows 7-x86-java]

        Show
        Roger Pack added a comment - I think this is fixed now, AFAICT. jruby 1.6.1 (ruby-1.8.7-p330) (2011-05-19 5790d31) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows 7-x86-java]
        Hide
        Thomas E Enebo added a comment -

        If Roger is wrong then please re-open. Resolving.

        Show
        Thomas E Enebo added a comment - If Roger is wrong then please re-open. Resolving.
        Hide
        Keith R. Bennett added a comment - - edited

        Never mind, I realize I was in error.

        Show
        Keith R. Bennett added a comment - - edited Never mind, I realize I was in error.
        Hide
        Keith R. Bennett added a comment -

        I was incorrect; it works as it should.

        Show
        Keith R. Bennett added a comment - I was incorrect; it works as it should.

          People

          • Assignee:
            Thomas E Enebo
            Reporter:
            Keith R. Bennett
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: