You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It seems that there have been some changes in JRuby 9.3 to the way Java and Ruby constructors interact when a reopened Java class with an initialize method is subclassed. I would consider these changes to be regressions; at least, if they are in fact intentional, I have seen no documentation explaining them.
In particular, the following specs (with accompanying Java classes below) all pass on JRuby 9.2.19.0, but four of them fail on JRuby 9.3.2.0:
describe"JRuby Java inheritance with JRuby #{JRUBY_VERSION}"doclassJava::Test::JRubyInheritanceTestdefinitialize(*args)opts=args.empty? ? nil : args[-1]super(opts ? opts[:arg] : "no options")trace.add"Ruby parent constructor called with #{args.inspect}"endendclassJava::Test::JRubyInheritanceTestSubclass# no constructorendsubclass_with_ctor=Class.new(Java::Test::JRubyInheritanceTest)dodefinitialize(*args)super(*args)trace.add"Ruby subclass constructor called with #{args.inspect}"endendsubsubclass_with_ctor=Class.new(Java::Test::JRubyInheritanceTestSubclass)dodefinitialize(*args)super(*args)trace.add"Ruby subsubclass constructor called with #{args.inspect}"endendshared_examples'stuff'do |args|
java_arg=args.empty? ? "no options" : args[-1][:arg]it'calls Ruby constructors first when constructing parent class'doobj=Java::Test::JRubyInheritanceTest.new(*args)expect(obj.trace).toeq(["Java parent constructor called with #{java_arg}","Ruby parent constructor called with #{args.inspect}"])endit'calls Ruby constructors first when constructing Ruby subclass'dosubclass=Class.new(Java::Test::JRubyInheritanceTest)obj=subclass.new(*args)expect(obj.trace).toeq(["Java parent constructor called with #{java_arg}","Ruby parent constructor called with #{args.inspect}"])endit'calls Ruby constructors first when constructing Ruby subclass with constructor'doobj=subclass_with_ctor.new(*args)expect(obj.trace).toeq(["Java parent constructor called with #{java_arg}","Ruby parent constructor called with #{args.inspect}","Ruby subclass constructor called with #{args.inspect}"])endit'calls Ruby constructors first when constructing Java subclass'doobj=Java::Test::JRubyInheritanceTestSubclass.new(*args)expect(obj.trace).toeq(["Java parent constructor called with #{java_arg}","Java subclass constructor called with #{java_arg}","Ruby parent constructor called with #{args.inspect}"])endit'calls Ruby constructors first when constructing Ruby subclass of Java subclass'dosubclass=Class.new(Java::Test::JRubyInheritanceTestSubclass)obj=subclass.new(*args)expect(obj.trace).toeq(["Java parent constructor called with #{java_arg}","Java subclass constructor called with #{java_arg}","Ruby parent constructor called with #{args.inspect}"])endit'calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor'doobj=subsubclass_with_ctor.new(*args)expect(obj.trace).toeq(["Java parent constructor called with #{java_arg}","Java subclass constructor called with #{java_arg}","Ruby parent constructor called with #{args.inspect}","Ruby subsubclass constructor called with #{args.inspect}"])endendcontext('with options hash'){include_examples'stuff',[{arg: 'foo'}]}context('with no args'){include_examples'stuff',[]}end
packagetest;
publicclassJRubyInheritanceTestSubclassextendsJRubyInheritanceTest {
publicJRubyInheritanceTestSubclass (Strings) {
super(s);
getTrace().add("Java subclass constructor called with " + s);
}
}
RSpec output on JRuby 9.2.19.0:
JRuby Java inheritance with JRuby 9.2.19.0
with options hash
calls Ruby constructors first when constructing parent class
calls Ruby constructors first when constructing Ruby subclass
calls Ruby constructors first when constructing Ruby subclass with constructor
calls Ruby constructors first when constructing Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor
with no args
calls Ruby constructors first when constructing parent class
calls Ruby constructors first when constructing Ruby subclass
calls Ruby constructors first when constructing Ruby subclass with constructor
calls Ruby constructors first when constructing Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor
Finished in 0.06475 seconds (files took 0.36651 seconds to load)
12 examples, 0 failures
RSpec output on JRuby 9.3.2.0:
JRuby Java inheritance with JRuby 9.3.2.0
with options hash
calls Ruby constructors first when constructing parent class
calls Ruby constructors first when constructing Ruby subclass
calls Ruby constructors first when constructing Ruby subclass with constructor (FAILED - 1)
calls Ruby constructors first when constructing Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor (FAILED - 2)
with no args
calls Ruby constructors first when constructing parent class
calls Ruby constructors first when constructing Ruby subclass
calls Ruby constructors first when constructing Ruby subclass with constructor (FAILED - 3)
calls Ruby constructors first when constructing Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass
calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor (FAILED - 4)
Failures:
1) JRuby Java inheritance with JRuby 9.3.2.0 with options hash calls Ruby constructors first when constructing Ruby subclass with constructor
Failure/Error: obj = subclass_with_ctor.new(*args)
ArgumentError:
wrong number of arguments for constructor
Shared Example Group: "stuff" called from ./spec/internals/jruby_inheritance_spec.rb:75
# ./spec/internals/jruby_inheritance_spec.rb:45:in `block in <main>'
2) JRuby Java inheritance with JRuby 9.3.2.0 with options hash calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor
Failure/Error: obj = subsubclass_with_ctor.new(*args)
ArgumentError:
wrong number of arguments for constructor
Shared Example Group: "stuff" called from ./spec/internals/jruby_inheritance_spec.rb:75
# ./spec/internals/jruby_inheritance_spec.rb:67:in `block in <main>'
3) JRuby Java inheritance with JRuby 9.3.2.0 with no args calls Ruby constructors first when constructing Ruby subclass with constructor
Failure/Error:
expect(obj.trace).to eq(["Java parent constructor called with #{java_arg}",
"Ruby parent constructor called with #{args.inspect}",
"Ruby subclass constructor called with #{args.inspect}"])
expected: ["Java parent constructor called with no options", "Ruby parent constructor called with []", "Ruby subclass constructor called with []"]
got: #<Java::JavaUtil::ArrayList: ["Java parent constructor called with no args", "Ruby subclass constructor called with []"]>
(compared using ==)
Shared Example Group: "stuff" called from ./spec/internals/jruby_inheritance_spec.rb:76
# ./spec/internals/jruby_inheritance_spec.rb:46:in `block in <main>'
4) JRuby Java inheritance with JRuby 9.3.2.0 with no args calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor
Failure/Error: obj = subsubclass_with_ctor.new(*args)
ArgumentError:
wrong number of arguments for constructor
Shared Example Group: "stuff" called from ./spec/internals/jruby_inheritance_spec.rb:76
# ./spec/internals/jruby_inheritance_spec.rb:67:in `block in <main>'
Finished in 0.11702 seconds (files took 0.39369 seconds to load)
12 examples, 4 failures
Failed examples:
rspec ./spec/internals/jruby_inheritance_spec.rb[1:1:3] # JRuby Java inheritance with JRuby 9.3.2.0 with options hash calls Ruby constructors first when constructing Ruby subclass with constructor
rspec ./spec/internals/jruby_inheritance_spec.rb[1:1:6] # JRuby Java inheritance with JRuby 9.3.2.0 with options hash calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor
rspec ./spec/internals/jruby_inheritance_spec.rb[1:2:3] # JRuby Java inheritance with JRuby 9.3.2.0 with no args calls Ruby constructors first when constructing Ruby subclass with constructor
rspec ./spec/internals/jruby_inheritance_spec.rb[1:2:6] # JRuby Java inheritance with JRuby 9.3.2.0 with no args calls Ruby constructors first when constructing Ruby subclass of Java subclass with constructor
Note that in three of the four failing cases the spec crashes with "ArgumentError: wrong number of arguments for constructor", while in one case (no args, Ruby subclass of Java parent class, with subclass constructor) the Ruby subclass constructor ends up calling the no-arg Java parent class constructor and skipping the Ruby parent class constructor entirely.
The text was updated successfully, but these errors were encountered:
class A < java.lang.Number
def initialize(config: )
super()
puts config.inspect
end
def m
puts "a"
end
end
module B
def m
puts "b"
super
end
end
A.new(config: {}).m
puts
A.prepend(B)
A.new(config: {}).m
puts
A.new.m
I would expect the output to be
{}
a
{}
b
a
ArgumentError (wrong number of arguments for constructor)
but instead, I get
{}
a
ArgumentError (wrong number of arguments for constructor)
b
a
ruby version: jruby 9.3.6.0 (2.6.8) 2022-06-27 7a2cbcd376 OpenJDK 64-Bit Server VM 11.0.15+10-Ubuntu-0ubuntu0.22.04.1 on 11.0.15+10-Ubuntu-0ubuntu0.22.04.1 [x86_64-linux]
It seems that there have been some changes in JRuby 9.3 to the way Java and Ruby constructors interact when a reopened Java class with an
initialize
method is subclassed. I would consider these changes to be regressions; at least, if they are in fact intentional, I have seen no documentation explaining them.In particular, the following specs (with accompanying Java classes below) all pass on JRuby 9.2.19.0, but four of them fail on JRuby 9.3.2.0:
Accompanying Java classes:
RSpec output on JRuby 9.2.19.0:
RSpec output on JRuby 9.3.2.0:
Note that in three of the four failing cases the spec crashes with "ArgumentError: wrong number of arguments for constructor", while in one case (no args, Ruby subclass of Java parent class, with subclass constructor) the Ruby subclass constructor ends up calling the no-arg Java parent class constructor and skipping the Ruby parent class constructor entirely.
The text was updated successfully, but these errors were encountered: