# JRuby constructor issue or just me?

**URL:** <https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532>\
**Category:** Ruby\
**Created:** [April 26, 2009, 11:50pm UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532 "2009-04-26T23:50:18Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 26, 2009, 11:50pm UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/1 "2009-04-26T23:50:18Z")

</div>

Hi,

I can’t figure out why this doesn’t work. I need to do this because I’m  
initializing the button elements separately within the constructor, but  
I want to ensure that the button is actually created first. I do this  
all the time with GTK+ & Ruby/GNOME2 on MRI, but it doesn’t seem to want  
to go with JRuby.

Is this problem something to do with the overloaded JButton  
constructors? How can I force a particular one to be called? I’ve read  
several Google results, but since I’m trying to call the JButton()  
constructor with no arguments, I can’t figure out what to do.

Any help would be appreciated.

Cheers,

ast

$ cat $HOME/jbutton.rb  
require ‘java’

include\_class ‘javax.swing.JButton’

class Foo \< JButton  
def initialize(count)  
super()  
self.text = “Foo”  
@count = count  
end  
end

foo = Foo.new

$ cat $HOME/output.txt  
nene$ c:/devel/src/jruby/bin/jruby -v  
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-26 r6586) (Java HotSpot™ Client  
VM 1.6.0\_13) [x86-java]  
nene$ c:/devel/src/jruby/bin/jruby jbutton.rb  
jbutton.rb:13: wrong # of arguments(0 for 1) (ArgumentError)

The above example is contrived to produce a suitable testcase, but based  
on the actual code that I’m trying to run.

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 27, 2009, 3:30am UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/2 "2009-04-27T03:30:09Z")

</div>

Andrew S. Townley wrote:

> $ cat $HOME/output.txt  
> nene$ c:/devel/src/jruby/bin/jruby -v  
> jruby 1.3.0 (ruby 1.8.6p287) (2009-04-26 r6586) (Java HotSpot™ Client VM 1.6.0\_13) [x86-java]  
> nene$ c:/devel/src/jruby/bin/jruby jbutton.rb  
> jbutton.rb:13: wrong # of arguments(0 for 1) (ArgumentError)

Constructors can be a little fiddly from within a Ruby class that  
extends a Java class, due to some complicated gymnastics. If at all  
possible you’d be better off aggregating the button, but if you must  
extend, extend with the same constructor style and just call “super”

We want to improve how this works, but the extension code needs a  
rewrite before that can happen. Contributing broken specs for cases like  
this that ought to “just work” would help us too.

- Charlie

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 27, 2009, 6:10am UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/3 "2009-04-27T06:10:27Z")

</div>

In Ruby, “super()” is different from just “super”. The former will  
invoke a superclass’ constructor with no parameters, while the latter  
will call it with the same number of parameters as was in “new” call.

Gennady.

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 27, 2009, 6:26am UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/4 "2009-04-27T06:26:16Z")

</div>

On Sun, Apr 26, 2009 at 4:49 PM, Andrew S. Townley [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> super()  
> self.text = “Foo”  
> @count = count  
> end  
> end
> 
> foo = Foo.new

Your initialize method requires at least a “count” parameter, but  
you’re not passing any. Do you mean to default it to something?

foo = Foo.new(42)

should work.

/Nick

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 27, 2009, 12:57pm UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/5 "2009-04-27T12:57:12Z")

</div>

Going to combine a few messages in one here:

On Mon, 2009-04-27 at 13:09 +0900, Gennady B. wrote:

> In Ruby, “super()” is different from just “super”. The former will  
> invoke a superclass’ constructor with no parameters, while the latter  
> will call it with the same number of parameters as was in “new” call.

Thanks. That’s exactly the behavior I wanted. I wanted to call the  
empty constructor explicitly.

On Mon, 2009-04-27 at 13:25 +0900, Nick S. wrote:

> Your initialize method requires at least a “count” parameter, but  
> you’re not passing any. Do you mean to default it to something?
> 
> foo = Foo.new(42)
> 
> should work.

Good catch, Nick. Test case error. I was incrementally trying to build  
up to the exact scenario that got the same error as my actual code.  
Unfortunately, I stopped when I got the error, rather than actually  
believing the compiler.

The original code didn’t have this problem.

On Mon, 2009-04-27 at 10:29 +0900, Charles Oliver N. wrote:

> extend, extend with the same constructor style and just call “super”
> 
> We want to improve how this works, but the extension code needs a  
> rewrite before that can happen. Contributing broken specs for cases like  
> this that ought to “just work” would help us too.

Thanks for the info here, Charlie. Unfortunately, I was barking up the  
wrong tree due to the message I got from jruby. I haven’t been able to  
duplicate it in a simple case, but the code that caused the problem was  
actually this:

28 class Button \< JButton  
29 def initialize(\*args, &block)  
30 super()  
31 if args.length \> 0 && args[0].is\_a?(Action)  
32 # action = args[0]  
33 self.action\_command = action.action\_id  
34 if action.status\_text.nil?  
35 self.tool\_tip\_text = action.label  
36 else  
37 self.tool\_tip\_text = action.status\_text  
38 end  
39 self.text = action.label

Originally, I didn’t have the reference in line 32 because I’d copied  
this code from another method where I was using aggregation instead of  
inheritance, which produced the following error:

excalibur$ jruby actiontest.rb  
…[path elided]/button\_peer.rb:33:in `initialize': wrong # of arguments(0 for 2) (ArgumentError) from actiontest.rb:46:in`initialize’  
from actiontest.rb:58

The call in actiontest.rb looks like this:

45 back = BackAction.new  
46 b1 = Button.new(back)

Since I hadn’t done the subclassing before, and the error was  
complaining about the constructor call, that’s where I started looking.  
I couldn’t figure out why the line number in the original error refers  
to the first time the JButton instance was used, however.

Since Nick pointed out that the empty call to JButton() actually works  
via ‘super()’, I went back to ensure that I wasn’t making the same  
mistake in the original code. This morning, I noticed that I had  
inadvertently lost the reference to the named action variable in the  
refactoring. After adding line #32, everything works swimmingly.

This is actually the kind of thing I was talking about when I said I was  
having to translate JRuby error messages.

Another case was when I was trying to give a derived AbstractAction  
sub-class, e.g.:

27 class ToggleAction \< AbstractAction  
28 def initialize(action)  
29 super(“Toggle Action State”)  
30 @action = action  
31 end  
32  
33 def actionPerformed(event)  
34 puts “perf”  
35 @action.enabled = !@action.enabled  
36 end  
37 end

Originally, since JRuby does method translation for action\_performed to  
actionPerformed, I’d implemented the class like this:

27 class ToggleAction \< AbstractAction  
28 def initialize(action)  
29 super(“Toggle Action State”)  
30 @action = action  
31 end  
32  
33 def action\_performed(event)  
34 puts “perf”  
35 @action.enabled = !@action.enabled  
36 end  
37 end

This gives the usefully obtuse (but totally accurate stack trace):

excalibur$ jruby actiontest.rb  
Exception in thread “AWT-EventQueue-0” java.lang.AbstractMethodError:  
org.jruby.proxy.javax.swing.AbstractAction$Proxy2.actionPerformed(Ljava/awt/event/ActionEvent;)V  
at  
javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)  
at  
javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)  
at  
javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)  
at  
javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)  
at  
javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)  
at java.awt.Component.processMouseEvent(Component.java:6134)  
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)  
at java.awt.Component.processEvent(Component.java:5899)  
at java.awt.Container.processEvent(Container.java:2023)  
at java.awt.Component.dispatchEventImpl(Component.java:4501)  
at java.awt.Container.dispatchEventImpl(Container.java:2081)  
at java.awt.Component.dispatchEvent(Component.java:4331)  
at  
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4301)  
at  
java.awt.LightweightDispatcher.processMouseEvent(Container.java:3965)  
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3895)  
at java.awt.Container.dispatchEventImpl(Container.java:2067)  
at java.awt.Window.dispatchEventImpl(Window.java:2458)  
at java.awt.Component.dispatchEvent(Component.java:4331)  
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)  
at  
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)  
at  
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)  
at  
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)  
at  
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)  
at  
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)  
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Admittedly, this one didn’t take me as long to figure out the root  
cause, but it still wasn’t very helpful in identifying the actual cause.  
Given that the behavior of “name mapping” isn’t 100% consistent (that it  
does it during calls, but not during definition), it might actually  
cause problems for more people than just me.

I know that JRuby isn’t the only implementation that does this (so does  
IronRuby), but it might be something to put on the “todo” list to at  
least provide some kind of warning or more automatic fixup.

While convenient, and certainly “more ruby-like”, I’m not really sure  
that doing all of the automagic method translation stuff is actually all  
that necessary, and, since it’s difficult to do for all cases without  
adding even more overhead, maybe might just be simpler to avoid.

I’m sure most people would disagree with me, but really, how much more  
of a PITA is it to do ‘rubyobj.addActionListener xyzzy’ than  
‘rubyobj.add\_action\_listener xyzzy’? At least you’ve some visual clue  
that you’re calling ‘native’ code here, and you don’t have to worry  
about knowing when the interpreter’s going to “do what you mean” vs. “do  
what you actually said”.

Overloaded methods are another kettle of fish… 🙂

Anyway, the problem’s solved now thanks to your collective help.  
Aggregation isn’t an option in this particular case (even though that’s  
my default approach), because what I need is a UI peer class that does  
some translation between an abstract toolkit’s concepts of buttons,  
actions, etc. and their “native” counterparts. All the peers need to be  
‘native’ so that they can be passed around to the appropriate classes  
where necessary in a consistent way vs. being ignored 99% of the time by  
the rest of the application code.

Glad it did turn out to be just me, but a more accurate error message  
would be nice.

Actually, as I was going to write the rest, I just figured out why I hit  
the problem. Action is an accessor of JButton. Since I used the same  
name, silent collision, the compiler’s happy, but it’s obviously still  
somewhat confused. Not really sure what message I’d expect, but I still  
think the current message is misleading.

At least now I understand what the issue was.

Cheers,

ast

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 27, 2009, 7:45pm UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/6 "2009-04-27T19:45:24Z")

</div>

Andrew S. Townley wrote:

> While convenient, and certainly “more ruby-like”, I’m not really sure  
> that doing all of the automagic method translation stuff is actually all  
> that necessary, and, since it’s difficult to do for all cases without  
> adding even more overhead, maybe might just be simpler to avoid.

Yes, we did make a modification in JRuby 1.1.5 or so to allow  
implementing interface methods with underscore names, but that never got  
into the class-extending code (which is way more complicated). We’re  
really tight on resources to work on this stuff, but we’re hoping to do  
another pass over the summer to complete the already-started rewrite of  
the whole Java integration layer. This sort of gap will be remedied then  
as well.

> Glad it did turn out to be just me, but a more accurate error message  
> would be nice.
> 
> Actually, as I was going to write the rest, I just figured out why I hit  
> the problem. Action is an accessor of JButton. Since I used the same  
> name, silent collision, the compiler’s happy, but it’s obviously still  
> somewhat confused. Not really sure what message I’d expect, but I still  
> think the current message is misleading.

There’s actually a bug in our tracker to improve error messages  
throughout Java integration code, since I know it can be very  
frustrating. The current code is unfortunately the product of almost 8  
years of people poking it this way and that without ever completing a  
full refactoring. But we’re untangling it bit by bit and making  
improvements with every release. We’re also more than willing to help  
folks like you sort out remaining issues.

And probably the biggest thing you could do to help us would be to  
contribute simple specs/tests for behaviors you discover and behaviors  
that aren’t working like you expect, so we can continue to build out a  
set of expectations we need to meet.

- Charlie

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 29, 2009, 2:10pm UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/7 "2009-04-29T14:10:21Z")

</div>

Andrew S. Townley wrote:

> > And probably the biggest thing you could do to help us would be to  
> > contribute simple specs/tests for behaviors you discover and behaviors  
> > that aren’t working like you expect, so we can continue to build out a  
> > set of expectations we need to meet.
> 
> Can you point me to the best documentation on how to do this? I’m happy  
> to help with the cases I’ve seen so far.

No specific docs, but if you check out JRuby (on github, jruby user’s  
jruby repository), there’s a spec/java\_integration directory with other  
examples. It’s pretty self-explanatory from there 🙂

- Charlie

---

<div class="post-metadata">

**Author:** ![Andrew\_SSTownley](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/d07c76/32.png) [@Andrew\_SSTownley](https://www.ruby-forum.com/u/Andrew_SSTownley)\
**Post date:** [April 29, 2009, 1:34pm UTC](https://www.ruby-forum.com/t/jruby-constructor-issue-or-just-me/166532/8 "2009-04-29T13:34:31Z")

</div>

On Tue, 2009-04-28 at 02:44 +0900, Charles Oliver N. wrote:

> another pass over the summer to complete the already-started rewrite of  
> the whole Java integration layer. This sort of gap will be remedied then  
> as well.

Sounds good. Hopefully the changing of the guard won’t interfere with  
this. 🙂

> throughout Java integration code, since I know it can be very  
> frustrating. The current code is unfortunately the product of almost 8  
> years of people poking it this way and that without ever completing a  
> full refactoring. But we’re untangling it bit by bit and making  
> improvements with every release. We’re also more than willing to help  
> folks like you sort out remaining issues.

That’s both very obvious and much appreciated. Thanks.

> And probably the biggest thing you could do to help us would be to  
> contribute simple specs/tests for behaviors you discover and behaviors  
> that aren’t working like you expect, so we can continue to build out a  
> set of expectations we need to meet.

Can you point me to the best documentation on how to do this? I’m happy  
to help with the cases I’ve seen so far.

Cheers,

ast
