Getting the Right Java Constructor

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

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[])

Interesting.

And yet this works using a more

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

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.

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