Auto-setter fails (wrapped java)?

require ‘java’

java_import ‘javax.swing.JFrame’
f = JFrame.new
f.set_location(100,100) # works
f.location= 100,100

last line fails with:
NameError: no setLocation with arguments matching [class
org.jruby.RubyArray] on object #Java::JavaxSwing::JFrame:0x1406eb6

Is this worthy of a JIRA?
Thanks!
-roger-

On Wed, Aug 10, 2011 at 7:45 AM, Roger P. [email protected]
wrote:

Is this worthy of a JIRA?
Thanks!
-roger-

No. A setter needs to have the right types as arguments.

Let’s see more in details:

f.location
=> #Java::JavaAwt::Point:0x9d9edd
f.location.class
=> Java::JavaAwt::Point

In jruby, ‘100,100’ is not of class Java::JavaAwt::Point. So you’ll
need to construct a point with the coordinates 100,100.

I would suggest instead to stick to java method setLocation, which
contains a nice constructor with coordinates as arguments.


Christian

On Wed, Aug 10, 2011 at 9:25 AM, Christian MICHON
[email protected] wrote:

No. A setter needs to have the right types as arguments. (…)

Here are 2 irb sessions to validate previous email: the 1st is the
original code without setter.
The 2nd is how your code should look like with setter.

require ‘java’
=> true
java_import ‘javax.swing.JFrame’
=> Java::JavaxSwing::JFrame
f = JFrame.new
=> #Java::JavaxSwing::JFrame:0x1a84b38
f.set_location(100,100)
=> nil
puts f.location
java.awt.Point[x=100,y=100]


require ‘java’
=> true
java_import ‘javax.swing.JFrame’
=> Java::JavaxSwing::JFrame
java_import ‘java.awt.Point’
=> Java::JavaAwt::Point
f = JFrame.new
=> #Java::JavaxSwing::JFrame:0x52c6f
f.location = Point.new(100,100)
=> #Java::JavaAwt::Point:0x933cba
puts f.location
java.awt.Point[x=100,y=100]


Christian

I’m using JRuby 1.6.2, and I’m trying to load but not instantiate
classes by name, and then introspect them.

require ‘java’
$CLASSPATH << ‘/some/path/classes’

class_loader = JRuby.runtime.jruby_class_loader
c = class_loader.load_class(“com.example.TestClass”)
p c
p c.class
p c.java_class

Which produces:

#Java::JavaLang::Class:0x67b2b131
Java::JavaLang::Class
class java.lang.Class

Now, I would expect that the returned class would be a subclass of
Class, i.e. com.example.TestClass. But, it does not appear to be so.
When I invoke “declared_instance_methods” on it (which I would expect to
be able to do if I had an the TestClass class), the method is not
defined.

Is load_class returning the correct value? If so, how can I get at the
methods (and fields, etc) defined on TestClass, without picking up the
additional JRuby defined classes?

Thanks,
Steve

If you look at the JavaDoc for loadClass you can see that it returns an
instance of class Class (
ClassLoader (Java Platform SE 7 )).
Class is a final class so you will never get a subclass of it, you will
just get an instance of it. I think what you want to call on this
object
is “getDeclaredMethods” or declared_methods in JRuby. That will return
you
an array of Method objects. That should get you to where you want to
go.

http://download.oracle.com/javase/7/docs/api/java/lang/Class.html#getDeclaredMethods()

Joe

On Wed, Aug 10, 2011 at 12:45 AM, Roger P. [email protected]
wrote:

Is this worthy of a JIRA?

I don’t think so.

We do add the location= method but it only works for arguments of type
java.awt.Point. Why? The second form would require passing two values
to an attribute assignment, which is not technically possible. You
can’t, for example, define your own attribute assignment method that
takes two args:

~ $ irb

def foo=(a, b); p a, b; end
=> nil
self.foo = 1, 2
ArgumentError: wrong number of arguments (1 for 2)
from (irb):2:in `foo=’
from (irb):2
self.foo=(1, 2)
SyntaxError: compile error
(irb):4: syntax error, unexpected ‘,’, expecting ‘)’
self.foo=(1, 2)
^
from (irb):4

This is perhaps a lacking in Ruby’s parser. It passes the 1, 2 as an
array, so it doesn’t match the arity of the target method. In the case
of setLocation, we see a single-argument call passing an Array, and
can’t find any overload of setLocation that matches it.

  • Charlie

On Fri, Aug 12, 2011 at 3:26 PM, Steve B. [email protected]
wrote:

Class as reflected in JRuby. But, sure enough, when I tried
I’m going to see if I can come up with a better inspect result for
that. It’s pretty useless like that.

puts “#{c.declared_methods}”

I got

“[Ljava.lang.reflect.Method;@5d90b72c

Which is Java internal notation for an array of Method objects. Which is
just what I want. I guess “p” is not the best way to examine objects :wink:

p is fine, but for Java arrays, it’s that ugly version above. Time to
fix it!

  • Charlie

On Sat, Aug 13, 2011 at 1:46 AM, Charles Oliver N.
[email protected] wrote:

p c.declared_methods

which produced

#<#Class:0x105735b26:0x7be536d6>

Better?

system ~/projects/jruby $ jruby -rjava -e “p [‘a’,
‘b’].to_java(:string)”
java.lang.String[a, b]@67d77351

system ~/projects/jruby $ jruby -rjava -e “p ‘foo’.to_java_bytes”
byte[102, 111, 111]@3b1af917

system ~/projects/jruby $ jruby -rjava -e “p
java.lang.Class.forName(‘java.lang.String’).declared_methods”
java.lang.reflect.Method[public boolean
java.lang.String.equals(java.lang.Object), public java.lang.String
java.lang.String.toString(), public int java.lang.String.hashCode(),
public int java.lang.String.compareTo(java.lang.Object), public int
java.lang.String.compareTo(java.lang.String), public int
java.lang.String.indexOf(java.lang.String), public int
java.lang.String.indexOf(int,int), public int
java.lang.String.indexOf(int), static int
java.lang.String.indexOf(char[],int,int,char[],int,int,int), public
int java.lang.String.indexOf(java.lang.String,int), public static
java.lang.String java.lang.String.valueOf(char[],int,int), public…

(the … above was my addition; it does actually show the whole array
contents)

  • Charlie

this looks really helpful - I am sure it will come in handy . . .

  • Kristian

On Sat, Aug 13, 2011 at 12:37 PM, Charles Oliver N.

MUCH better! I did find, that for java.lang.String, the class seemed to
print out more informatively. Try doing it for classes loaded via the
class loader that aren’t native to the JVM – if they print out as you
indicate, it will be a HUGE win.

Thanks!

It is done! I also confirmed it works with arbitrary classes:

system ~/projects/jruby $ jruby -rjava -e ‘$CLASSPATH <<
“build/classes/test”; ary = [nil].to_java
org.jruby.test.bench.BenchFixnumFibRecursive; p ary’
org.jruby.test.bench.BenchFixnumFibRecursive[null]@354d581b

  • Charlie

Sweet! Thanks Charlie!

Thanks Joe – you’ve led me in the right direction. Where I was getting
confused, I would do

p c.declared_methods

which produced

#<#Class:0x105735b26:0x7be536d6>

Which didn’t look very useful – to me it looked like just another
flavor of Class as reflected in JRuby. But, sure enough, when I tried

puts “#{c.declared_methods}”

I got

“[Ljava.lang.reflect.Method;@5d90b72c

Which is Java internal notation for an array of Method objects. Which
is just what I want. I guess “p” is not the best way to examine objects
:wink:

Thanks again,
Steve