Forum: JRuby Getting the Right Java Constructor

486ca04f06d968004643ce5b47376ded?d=identicon&s=25 Keith B. (keith_b)
on 2013-05-09 02:14
(Received via mailing list)
All -

I need to get the right constructor overload.  For some reason,
iterating
over all the constructors and matching the parameter types works, but
using
the 'constructor' method does not:

    # java_message_class =
java.lang.Class.forName('org.xbill.DNS.Message')
    byte_array_class = java.lang.Class.forName('[B')

# constructor = java_message_class.constructor(byte_array_class)

    # p
    # p byte_array_class
    # p
    # p "Constructors:"
    constructor = Message.java_class.constructors.detect do |c|
      c.parameter_types == [byte_array_class]
    end
1273e5c266e0c4cc4065fff3a6fe7056?d=identicon&s=25 Anthony Juckel (Guest)
on 2013-05-09 03:31
(Received via mailing list)
I wonder a bit why you're going down this road.  I think
reflection-heavy
code is probably better left to Java code that you load within JRuby,
rather than doing Java reflection directly in Ruby code.

But, if you're set on your path, I believe you simply mistyped the
method
name.  You're looking for getConstructor (or get_constructor).

Assuming you have the following class on your classpath:

  public class Message {
      public Message(byte[] bytes) {
      }
  }

Then this works fine:

irb(main):001:0> import 'Message'
=> [Java::Default::Message]
irb(main):002:0> m_class = java.lang.Class.for_name("Message")
=> class Message
irb(main):003:0> b_class = java.lang.Class.for_name("[B")
=> class [B
irb(main):004:0> m_class.get_constructor(b_class)
=> public Message(byte[])
2553a4e57589e8d210aaf7c1e29906c9?d=identicon&s=25 "Sébastien Le Callonnec" <slc_ie@yahoo.ie> (Guest)
on 2013-05-10 08:34
(Received via mailing list)
Interesting.

And yet this works using a more
486ca04f06d968004643ce5b47376ded?d=identicon&s=25 Keith B. (keith_b)
on 2013-05-10 18:28
(Received via mailing list)
Anthony and Sebastien -

Thanks for your help.

Anthony, using 'constructor' as the method name worked (try it if you
don't
believe me).  JRuby aliases Java accessors and mutators not only in the
usual way (that is, in snake case), but also in conventional Ruby
notation
(like attr_accessor would).

- Keith
1273e5c266e0c4cc4065fff3a6fe7056?d=identicon&s=25 Anthony Juckel (Guest)
on 2013-05-10 20:01
(Received via mailing list)
The constructor method is there,  I agree,  but I don't believe for the
reason you think.

I thought you were looking at the raw Java Class. The constructor method
you're referring to is provided by JavaClass, the JRuby proxy for a raw
Java Class object.  And it expects another (proxy) JavaClass as an
argument.  Using java.lang.Class.for_name returns an unproxied Java
Class.

I believe dropping the get only works for JavaBean property (no arg)
getter
methods.
486ca04f06d968004643ce5b47376ded?d=identicon&s=25 Keith B. (keith_b)
on 2013-05-10 21:40
(Received via mailing list)
Guys -

You were right and I was wrong.  First of all, this:

      Message.java_class.declared_constructor([].to_java(:byte).java_class)

...worked perfectly. Secondly, I forgot that the attr_accessor type
aliases
only apply to beanlike signatures.

Thanks so much for the corrections.  Everything's working great now.

- Keith
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.