"I have a mind like a steel... uh... thingy." Patrick Logan's weblog.

Search This Blog

Sunday, November 18, 2007

JRuby and JXPath

Final Update:

Bottom line: for the current implementation of JRuby implementing this does not seem possible. A near-future release is supposed to improve on the Java/Ruby integration. In this case what is needed:

  • A Java class that is the superclass of all JRuby classes. Similar to the PyInstance class (a Java class) in the Jython implementation.
  • A Java class that corresponds to a class defined in JRuby such that when instantiated via newInstance() in Java also creates a corresponding JRuby instance. Similar to the JythonPropertyHandler class I defined in Jython, corresponding to the JRubyPropertyHandler class I attempted to define in JRuby, below.
End Update

Sometimes I drink to forget, and sometimes I just forget. Several years ago I blogged about using JXPath to query Jython objects. Sometime since then I forgot all about JXPath. I remember it now being fairly simple, and working with all kinds of structures. (And so JXPath should be a fairly simple way to use XPath to query JSON objects in Java, BTW.)

I started playing with JRuby recently to see how it's doing. When I came across the Jython code I just mentioned, I thought I'd try the equivalent in Jruby. Here's what I have so far, but I have two question marks preventing it from running. I sent them to the JRuby users list, but if anyone reading this has an answer or a hint, I'd appreciate that.

class JRubyPropertyHandler 
  include org.apache.commons.jxpath.DynamicPropertyHandler

  def getPropertyNames(robject)
    return robject.instance_variables.to_java
  end

  def getProperty(robject, property)
    if robject.instance_variables.include?(property)
      robject.instance_variable_get(property)
    else
      nil
    end
  end

  def setProperty(robject, property, value)
    robject.instance_variable_set(property, value)
  end

  def JRubyPropertyHandler.register()
    introspector = org.apache.commons.jxpath.JXPathIntrospector
    introspector.registerDynamicClass(???, ???)
  end
end
It's that call to registerDynamicClass (javadoc) that has me stumped. The first argument is a class of all the instances that should be handled by JRubyPropertyHandler.

The second argument ideally should just be JRubyPropertyHandler. i.e. not an instance of the handler, but the handler class itself.

I tried calling...

    introspector = org.apache.commons.jxpath.JXPathIntrospector
    introspector.registerDynamicClass(Object, JRubyPropertyHandler)
But these two arguments are each instances of org.jruby.RubyClass, not java.lang.Class as needed.

In Jython the two arguments to register a handler are PyInstance, the Java class that is the superclass of all Jython instances, and the handler class itself. The code for my working Jython implementation is on my original blog post.

Update: from the jruby user's mail list, Nick Sieger drops a good hint, and I have more questions until I can get back to a jirb prompt...

> Perhaps this snippet helps?
>
> $ bin/jruby -S irb
> irb(main):001:0> class Foo
> irb(main):002:1> include java.lang.Runnable
> irb(main):003:1> end
> => Foo
> irb(main):004:0> Foo.new.java_class
> => $Proxy7

Thanks. Maybe. I'll look into it when I can get back to my jirb prompt.

That will work for the second argument *if* it implies that when the
jxpath java code creates a new instance of $Proxy7 then what actually
happens is a new jruby instance of Foo is created.

But what does this say about all jruby objects?

i.e. in jruby, they are all instances of the class Object, but if I do
the following...

o = Object.new
j = o.java_class

...then can I assume that all jruby objects are (in java-land)
instances of a java class that inherits from "j"?

Or is the java_class $ProxyN class more of an on-demand, dynamically
generated, bridge to the other world?

No comments:

Blog Archive

About Me

Portland, Oregon, United States
I'm usually writing from my favorite location on the planet, the pacific northwest of the u.s. I write for myself only and unless otherwise specified my posts here should not be taken as representing an official position of my employer. Contact me at my gee mail account, username patrickdlogan.