JRuby objects in Scala


#1

JRubyat,

i’ve really been stymied by various approaches to use JRuby objects from
any
other JVM language. At the time of this writing, my currently best
performing, non-buggy approach is to covert to YAML and convert back via
jvyaml (see below). This really feels like it defeats the purpose of JVM
level interop. There must be a better way. What am i missing?

Best wishes,

–greg

bash-3.2$ script/console
script/console
Loading development environment (Rails 2.1.1)
JRuby limited openssl loaded. gem install jruby-openssl for full
support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL

cas = MyProjActivities.new
cas = MyProjActivities.new
=> #<MyProjActivities id: nil, name: nil, creator_id: nil, owner_id:
nil,
uuid: nil, created_at: nil, updated_at: nil, visibility: “public”,
status:
“open”, sharing: “anyone”>

cas.to_yaml
cas.to_yaml
=> “— !ruby/object:MyProjActivities\nnew_record: true\nattributes: \n
owner_id: \n name: \n updated_at: \n creator_id: \n uuid: \n
visibility: public\n created_at: \n status: open\n sharing:
anyone\nattributes_cache: {}\n”

bash-3.2$ mvn scala:console
[INFO] Scanning for projects…
[INFO] Searching repository for plugin with prefix: ‘scala’.
[INFO]

[INFO] Building dspace
[INFO] task-segment: [scala:console]
[INFO]

[INFO] Preparing scala:console
Welcome to Scala version 2.7.3.final (Java HotSpot™ Client VM, Java
1.5.0_16).
Type in expressions to have them evaluated.
Type :help for more information.

scala> org.jvyaml.YAML.load("—
!ruby/object:MyProjActivities\nnew_record:
true\nattributes: \n owner_id: \n name: \n updated_at: \n
creator_id:
\n uuid: \n visibility: public\n created_at: \n status: open\n
sharing:
anyone\nattributes_cache: {}\n")
org.jvyaml.YAML.load("— !ruby/object:MyProjActivities\nnew_record:
true\nattributes: \n owner_id: \n name: \n updated_at: \n
creator_id:
\n uuid: \n visibility: public\n created_at: \n status: open\n
sharing:
anyone\nattributes_cache: {}\n")
org.jvyaml.YAML.load("— !ruby/object:MyProjActivities\nnew_record:
true\nattributes: \n owner_id: \n name: \n updated_at: \n
creator_id:
\n uuid: \n visibility: public\n created_at: \n status: open\n
sharing:
anyone\nattributes_cache: {}\n")
res0: java.lang.Object = #<PrivateType tag:
!ruby/object:MyProjActivities
value: {attributes={visibility=public, updated_at=null, owner_id=null,
creator_id=null, uuid=null, created_at=null, sharing=anyone,
status=open,
name=null}, new_record=true, attributes_cache={}}>

scala>


L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com


#2

On 10 Mar 2009, at 23:41, Meredith Gregory wrote:

Best wishes,

–greg

I may be way off here, but if I understand your question correctly you
could either:

  1. Make it easy on scala and implement an interface / trait in ruby.
  2. Make it easy on ruby and call methods on IRubyObject in scala.

in the medium / long term hopefully you will have these options:

  1. MOP http://dynalang.sourceforge.net/ rather than IRubyObject.
  2. JRuby compiler
    http://blog.headius.com/2009/03/compiling-ruby-to-java-types.html

There will never be a completely smooth interface between static and
dynamic languages, I suppose. Option 1 strikes me as the better choice
currently.

Hope this helps,

Damian


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

#3

Damian,

Thanks for your note. The point of moving objects from JRuby -> Scala is
performance and reliability. So, while option 1 is “easy” it is neither
typed nor as fast. Option 2 is also problematic and ends up with a lot
of
code essentially emulating what the JRuby interpreter does. i’m starting
to
feel like JRuby is like the IOMonad in Haskell, things go in, but they
don’t
come out. :wink:

Best wishes,

–greg

On Tue, Mar 10, 2009 at 6:00 PM, Damian S. removed_email_address@domain.invalid wrote:

level interop. There must be a better way. What am i missing?

  1. Make it easy on scala and implement an interface / trait in ruby.
    currently.


L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com


#4

Interface impl should be reasonably fast, or at least not significantly
slower than calling ruby-to-ruby. Where it does suffer, however, is in
passing strings, since we need to encode and decode them both ways. Are
you running into some specific performance problems?

Meredith Gregory wrote:

    i've really been stymied by various approaches to use JRuby
    --greg

Damian


L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

#5

Charles,

Many thanks for your reply. Not surprisingly, we see factors of 3 and
above
perf improvement moving code from JRuby to Java. Writing that same Java
code
in Scala also gives similar perf improvement, while providing both
functional programming paradigm and rich static typing. Option 1
mentioned
by Damian in the thread below, if i have understood the proposal, is
tantamount to leaving code running in JRuby – which defeats our
purpose.
Option 2 has other challenges primarily of the form that we are now
doing
what the JRuby interpreter does for a whole bunch of dispatching logic.

i have analyzed our situation and realize that the 80% case is that we
want
to put business logic around model objects. These model objects are
essentially POJOs. So, we ought to be able to construct a scheme that
efficiently marshals the JRuby model objects into POJOs that we have
generated from a schema associated with the model objects, e.g. the SQL
schema. Doing this would get us statically available type info and allow
us
to write clear, simple code in Scala. (Well, as simple as the Scala
syntax
allows… :wink:

i have yet to find a maintainable, performant marshaling scheme that
doesn’t
amount to going out to a string and back to the POJO. Maintainable is
also a
consideration here. i could be wrong, and seek your guidance on this
point,
but it seems, quite apart from the fact that it would have to do a lot
of
what the JRuby interpreter is doing, code that makes a lot of calls
against
JRubyObject is more likely to be impacted by the evolution of JRuby,
than
the code pattern illustrated below. The former strategy means we have to
keep up with how to use the JRubyObject interface and how and when to
use
ThreadContexts and other information about the JRuby execution model.
The
strategy illustrated in the code fragment below means we bet that the
interface to getting stuff in and out of YAML (i.e. dump/load) doesn’t
change – and that we let YAML deal with circular references and
structure
traversal, etc.

#JRuby entry point
def transitionFromFrontEndToBusinessLogic

javaContainerForResults = myBusinessLogicInScala(
myModelObj.to_yaml )

  ...
  # calculate stuffToRender from business logic results
  ...
  render ( :xml => stuffToRender)

end

// Scala entrypoint
def myBusinessLogicInScala( marshaledPOJO : string ) :
JavaResultsContainerClass = {
val protoPOJO = org.jvyaml.YAML.load( marshaledPOJO )

// do stuff and fill in results container class

javaContainerForResults
}

Best wishes,

–greg

On Wed, Mar 11, 2009 at 9:08 AM, Charles Oliver N. <
removed_email_address@domain.invalid> wrote:

performance and reliability. So, while option 1 is “easy” it is neither
removed_email_address@domain.invalid>> wrote:
back via
I may be way off here, but if I understand your question correctly

806 55th St NE

http://xircles.codehaus.org/manage_email


L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com


#6

Charles,

Thanks for your query. We’ve got a large app written primarily in JRuby.
Perf analysis gives the results reported below. So, there are sections
of
our app we want to move to Java and see Scala as a way of essentially
writing Java with a language a little closer to the productivity of
JRuby.
Going forward we are moving in the architectural direction you mention
below: JRuby frontend Scala-SOA architecture backend. Does that help?

The sample code was to indicate an approach to marshaling. It’s one way
to
get data backand forth between JRuby and Scala. Specifically,

  • JRuby can just use POJOs.
  • Scala can get at the data in the Hashmap provided by the unmarshal
    from
    jvyaml and populate the POJO.

Therefore the roundtrip path (frontend to business logic + services back
to
frontend) of least resistence for an app of this kind seems to be

  • JRuby -> Scala/Java – marshal to YAML, unmarshal from YAML, fill
    in
    POJO, do stuff
  • Scala/Java -> JRuby – hand over the POJO

If i’m wrong, i’d love to understand a kinder-simpler roundtrip. (Sorry,
i
should have updated the idiom with the administration change. i can haz
easy
roundtrip from JRuby to Scala and back?)

Best wishes,

–greg

On Wed, Mar 11, 2009 at 10:01 AM, Charles Oliver N. <
removed_email_address@domain.invalid> wrote:

Option 2 has other challenges primarily of the form that we are now doing

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


L.G. Meredith
Managing Partner
Biosimilarity LLC
806 55th St NE
Seattle, WA 98105

+1 206.650.3740

http://biosimilarity.blogspot.com


#7

Meredith Gregory wrote:

of dispatching logic.
I guess I’m confused what you’re actually using JRuby for, since
“leaving code in JRuby” defeats your purpose. What are you using JRuby
for? Just YAML access? Is the sample code you showed a Rails app, and
you want to toss data over the fence for Scala to process it?

Is this a case where you want to have Rails + AR frontend, but a Scala
business tier processing the results more quickly for you?

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

#8

Meredith Gregory wrote:

* JRuby -> Scala/Java -- marshal to YAML, unmarshal from YAML, fill
  in POJO, do stuff
* Scala/Java -> JRuby -- hand over the POJO

If i’m wrong, i’d love to understand a kinder-simpler roundtrip. (Sorry,
i should have updated the idiom with the administration change. i can
haz easy roundtrip from JRuby to Scala and back?)

Ok, you have most of the facts correct:

  • Ruby objects are not “normal” Java objects you’d be able to manipulate
    directly.
  • Marshalling is probably the simplest way to communicate across the
    Ruby/Java gap, though most mechanisms will be somewhat slow due to all
    the string-wrangling.
  • In addition, string-wrangling can be especially expensive because
    JRuby’s strings are byte[] and Java’s strings are char[]; there’s
    decoding/encoding required both ways.

The best-performing way to do this would probably be to have Ruby
populate existing POJOs you can then pass out to the Scala code. You’d
still have some issues with the string transcoding, but it would be
reduced.

To be honest, though, up to now most people have not used JRuby with
Java-like backends across an especially chatty interface, which is what
you have here. There’s overhead calling back and forth from static to
dynamic and back, and the more round trips you make the more overhead
you introduce. We’re certainly working every release to reduce that
overhead, and trying to move toward the Java integration layer being as
fast as possible, but right now there’s still work to do.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email