Serializing Ruby objects from Java

Hi,

I am wondering how I can serialize a class written in Ruby from Java.

The Java codebase that I am working on expects some classes to be
serializable to be able to execute the custom operations that they
provide on other JVMs. I wanted to provide a Ruby integration that
allows to implement some of those classes in Ruby.

A minimal example would be something like this:

include_class “java.io.Serializable”
include_class “java.lang.Runnable”

class MyRunnable
include Serializable, Runnable

def initialize()
    @num = 0
end

def run()
    @num += 1
    puts "Called #{@num} times"
end

end

MyRunnable.new

In this case the Java code expects this class to implement the
Runnable interface. I have also made it implement Serializable in the
hope that this helps making it serializable.

When I get the MyRunnable instance from Java using something like:
Runnable runnable = (Runnable) rubyEngine.eval(script);

I can’t write this object to an ObjectOutputStream. If I do this, I
get this Exception:
Exception in thread “main” java.io.NotSerializableException:
org.jruby.RubyClass$VariableAccessor
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:
1156)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:
1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:
1474)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:
1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:
1150)

I am using JRuby 1.3.0. Is there a way to serialize objects written in
Ruby from Java? Would I be able to deserialize these objects on a
different virtual machine? I am wondering how this would get attached
to a JRuby runtime.

Any ideas?

Thanks,
–Peter


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Sat, Jun 13, 2009 at 2:35 AM, Peter Voss[email protected] wrote:

Hi,

I am wondering how I can serialize a class written in Ruby from Java.

The Java codebase that I am working on expects some classes to be
serializable to be able to execute the custom operations that they provide
on other JVMs. I wanted to provide a Ruby integration that allows to
implement some of those classes in Ruby.

I can’t write this object to an ObjectOutputStream. If I do this, I get this
Exception:
Exception in thread “main” java.io.NotSerializableException:
org.jruby.RubyClass$VariableAccessor

At the moment, this is not possible. Because every Ruby object needs
to have a reference to an org.jruby.Ruby instance, which does not have
a “global” or “static” instance, there’s no way to serialize Ruby
objects with normal Java serialization. It’s one of the gaps we’re
hoping to fill this summer. Your best option for now would probably be
to write a Java data-carrying object and serialize that.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hi,

On 14.06.2009, at 20:46, Charles Oliver N. wrote:


hoping to fill this summer. Your best option for now would probably be
to write a Java data-carrying object and serialize that.

Ok, great. Is there an issue that I could track or even make
contributions to?

Regarding the data-carrying object: How would I then transfer the
actual ruby code and create a new instance? I am new to JRuby and more
a Java programmer. In the Java world I have to have the class file of
the object that I want to deserialize on the class path. But the Ruby
object is defined in a script that might contain class definitions
plus some business logic. Something like:

1000.times do |x|
puts x
end

class SomeClass

end

To create a new instance of SomeClass (as part of the deserialization)
I can’t simply eval the full Ruby script to create a new instance of
SomeClass. Any ideas on how to achieve that?

Thanks for your help,
–Peter

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Mon, Jun 15, 2009 at 8:08 AM, Peter Voss[email protected] wrote:

On 14.06.2009, at 20:46, Charles Oliver N. wrote:

At the moment, this is not possible. Because every Ruby object needs
to have a reference to an org.jruby.Ruby instance, which does not have
a “global” or “static” instance, there’s no way to serialize Ruby
objects with normal Java serialization. It’s one of the gaps we’re
hoping to fill this summer. Your best option for now would probably be
to write a Java data-carrying object and serialize that.

Ok, great. Is there an issue that I could track or even make contributions
to?

Hmm, not really at the moment, but we probably should start talking
about it…right here?

The basic issue, in simple terms, is that JRuby objects always take an
org.jruby.Ruby instance in their constructors. So while we could
easily serialize the data associated with an object, once loaded on
the other side by Java deserialization logic, there’s no Ruby instance
present.

It’s become increasingly apparent, however, that for tight integration
with Java we need a way to eliminate this constructor dependency. The
simplest way I can think of would be to make all JRuby objects rely on
a single classloader-global Ruby instance. Then deserialization,
object construction from Java, method invocation…all become a lot
easier. What we lose is the ability to just “new” a Ruby instance and
start using it, but I think we can follow a path similar to Groovy
here as well, providing a RubyEngine or RubyClassLoader that people
construct for the same purpose.

What users like you could do would be to discuss as much as you can
think of here on this thread, and maybe spike a prototype of
RubyBasicObject/RubyObject that have a no-arg constructor and use the
global runtime (already available for ruby2java, which produces normal
Java classes from Ruby code).

Have any thoughts or ideas on how this should all work?

class SomeClass
  …
end

To create a new instance of SomeClass (as part of the deserialization) I
can’t simply eval the full Ruby script to create a new instance of
SomeClass. Any ideas on how to achieve that?

As with Ruby marshalling or Java serialization, you’d need to have
that class already available in the target runtime. That may mean
shipping a set of “bootstrap” scripts or something similar. There’s no
real difference here from Java serialization…you just have a few
more options to consider for how to get those classes loaded ahead of
time.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

There is a Java library now available to read/write the Ruby
serialization format in Java.

http://code.google.com/p/mfz-ruby-marshal/