Serializing Ruby objects from Java

View: New views
4 Messages — Rating Filter:   Alert me  

Serializing Ruby objects from Java

by Peter Voss :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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



Re: Serializing Ruby objects from Java

by Charles Oliver Nutter-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Jun 13, 2009 at 2:35 AM, Peter Voss<info@...> 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



Re: Serializing Ruby objects from Java

by Peter Voss :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

On 14.06.2009, at 20:46, Charles Oliver Nutter wrote:

> On Sat, Jun 13, 2009 at 2:35 AM, Peter Voss<info@...> 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.

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



Re: Serializing Ruby objects from Java

by Charles Oliver Nutter-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Jun 15, 2009 at 8:08 AM, Peter Voss<info@...> wrote:

> On 14.06.2009, at 20:46, Charles Oliver Nutter 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?

> 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?

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