Talking to Java APIs

I’m trying to figure out how Ruby in general, and/or anything extra
Rails may have, can talk to Java APIs of third party server apps.

After quite a few search attempts net-wide and on ruby forums, and
with “Programming Ruby” in hand, I’m coming up with zilch. Either I’m
not finding it, or I’m not recognizing it.

I’m assuming there has to be a Ruby API that allows someone to write
some Java, wrap it, and have Ruby send params and recieve some
results via that wrapped up Java chunk?

Any clues to point me in the right direction? THX.

– greg willits

On 8/15/06, Greg W. [email protected] wrote:

results via that wrapped up Java chunk?

Any clues to point me in the right direction? THX.

Well there’s certainly JRuby :slight_smile:

require ‘java’
include_class “java.lang.System”
System.out.println(“Hello Java in Ruby!”)

There’s also a number of Ruby/Java bridges of various qualities: rjb,
yajb

Finally, there’s the stock recommendation: put your Java code behind a
web
service.

Naturally, I prefer the JRuby route. YMMV.

Web services? Can you wrap your Java APIs in a Web service, and call
them via that?

The issue you describe is generic, and pops up nearly every time you
cross from one architecture to another (e.g. J2EE to .NET); it’s not a
Ruby/Rails-specific issue The main solution classes are to either use
a software product to “bridge” between the architectures (e.g. a
dedicated bridge product for the two protocols, or use something like
MQ), or to wrap one or both architecture’s APIs with a Web service
wrapper of some sort.

Enterprise Integration with Ruby has quite a bit on interoperability.
In particular, the discussion of RMI is probably relevant.

Bill

On Aug 15, 2006, at 2:33 PM, Charles O Nutter wrote:

On 8/15/06, Greg W. [email protected] wrote:
I’m trying to figure out how Ruby in general, and/or anything extra
Rails may have, can talk to Java APIs of third party server apps.

Well there’s certainly JRuby :slight_smile:
www.jruby.org

require ‘java’
include_class "java.lang.System "
System.out.println(“Hello Java in Ruby!”)

I know I’ve bumped into this before but all the descriptions made it
sound like it was designed to execute Ruby syntax inside Java (the
opposite of my task).

I’ll have a closer look. Thanks.

– gw

Greg W. wrote:

I know I’ve bumped into this before but all the descriptions made it
sound like it was designed to execute Ruby syntax inside Java (the
opposite of my task).

It is. The point being made was that, once you’re executing Ruby inside
the JVM, you can then call out to other things (java code) inside the
same
JVM.

In particular, you could then execute Java code that talks to your third
party server applications.

Bill

On Tue, 2006-08-15 at 14:28 -0700, Greg W. wrote:

Any clues to point me in the right direction? THX.

There YAJB (Yet Another Java Bridge):

http://www.cmt.phys.kyushu-u.ac.jp/~M.Sakurai/cgi-bin/fw/wiki.cgi?page=YAJB

Yours,

tom

Wouldn’t the right direction be to not use Java at all? :stuck_out_tongue:

On Aug 15, 2006, at 2:37 PM, David M. wrote:

Web services? Can you wrap your Java APIs in a Web service, and call
them via that?

“Can”–probably, but this would not be a good solution in this case.

I need to connect a lightweight web app to a very dense core of Java
tools (search oriented server side engine, and others). Exploring RoR
and others for the front end. I need to take search params from the
web app, and pass them as directly as possible into the Java app.

The issue you describe is generic, and pops up nearly every time you
cross from one architecture to another (e.g. J2EE to .NET); it’s not a
Ruby/Rails-specific issue

Understood.

The main solution classes are to either use
a software product to “bridge” between the architectures (e.g. a
dedicated bridge product for the two protocols, or use something like
MQ), or to wrap one or both architecture’s APIs with a Web service
wrapper of some sort.

I’m used to another language I’ve used the past few years (not very
widely used), which has both a Java and C API built in for doing
exactly this–exchanging basic params/results between the languages
to either connect to services or implement an algorithm in lower
level code. As you say, I would expect it to be a pretty common need,
so I expected to see Ruby with something built-in too.

MQ–new to me. I’ll follow the google leads I’m finding and see where
that takes me. Thanks.

– gw

results via that wrapped up Java chunk?

Any clues to point me in the right direction? THX.

– gw

Greg W. wrote:

that the whole app is actually running in a Java container, and it uses
some Ruby syntax in it so there’s no need to write Java. That’s not what
I’m trying to acheive.

Nevertheless, I’ll dig further into JRuby to understand it better.

Let me say it a slightly different way.

  1. Java is a programming language.
  2. The JVM (java virtual machine) is a platform for executing “bytecode”
  3. Java compiles into bytecode, which then gets executed on the JVM.
  4. JRuby is a Java application which compiles Ruby to bytecode which can
    be executed on a JVM (NOT using the standard ruby binaries).
  5. The way you run Ruby applications “inside Java” is to use JRuby as a
    compiler, which compiles the Ruby code to bytecode, which the JVM
    then
    executes.
  6. Because the Ruby is compiled to bytecode, and because Java programs
    are
    compiled to bytecode, there’s no reason at all why your ruby code
    couldn’t
    talk to java code (the JVM certainly doesn’t know the difference).

So let’s look at Charles’s code:

require 'java'
include_class "java.lang.System "
System.out.println("Hello Java in Ruby!")

That’s Ruby! JRuby can compile it and it will run in the JVM, but it’s
Ruby.
He could just as easily have written

require 'java'
include_class "java.lang.System "
System.out.println("Hello Java in Ruby!")
puts "My spleen is made of stainless steel"

just to make the point (that it’s ruby code) clearer.

But it’s ruby code that requires ‘java’ and then calls to a java method
(println, on System.out). And you have to be running your entire
application
on a JVM (with JRuby) to make it work.

Does that help?

Bill

On 8/15/06, Greg W. [email protected] wrote:

See, now for whatever reason, this is one of those things that my
brain is refusing to grab a hold of and just “get.”

I can understand running Ruby inside Java. Easy concept. However, I
don’t want to run Ruby inside Java, I just want to pass some data
from Ruby to Java. Have Java do some things, and then pass some data
back to Ruby. Without using web services. Once inside Java, the code
will be Java.

I’ll try to make it a bit more clear; I know that for a non-Java
programmer
it’s a little weird.

JRuby is an implementation of Ruby, plain and simple. The difference is
that
instead of being written in C and running as a C program, it’s written
in
Java and runs as a Java program. That does necessitate that it’s running
inside a JVM, like any Java program, but otherwise it works like Ruby.
You
can run “jruby script.rb” and it will run, like it would with normal
Ruby.
However you can call Java code from inside that script, and it’s pretty
easy
to do. It’s somewhat akin to Kernel#syscall for normal Ruby…you’re not
launching another process or making a remote call to call Java…JRuby
just
does some magic to make the call happen and appear to be normal Ruby
code.
Other than calls to Java, a Ruby script in JRuby looks like like a Ruby
script in normal Ruby. JRuby isn’t perfect yet, but it can run most Ruby
core libraries and simple Rails apps. It’s under heavy development, and
we’re making great progress on performance and compatibility.

That said, JRuby may or may not be the option you want. If you prefer to
use
stock Ruby, or if you’re not really into or experienced with Java in
general, JRuby may be overkill for your needs. The Ruby/Java bridges
would
allow you, theoretically, to call your Java library of choice as in
JRuby
with only a little more overhead. You’ll need to choose what works for
you.

JRuby is usually the best option if you have Java libraries you want to
be
able to use from your Ruby code, but it’s not always the best option and
certainly not the only option. If you do choose to go down the JRuby
route,
the other devs and I will certainly try to help you make your app work
right.

Incidentally, there’s now an additional option for remoting with JRuby:
DRb.
Apparently some users now have DRb working well enough under JRuby that
you
could put your Java code behind a DRb service rather than behind a SOAP
web
service. That’s pretty compelling considering the complexity and
overhead of
SOAP. We also have plans in the future to implement “smart” proxies to
map
DRb automatically to the various types of Java EE services.

On Aug 15, 2006, at 2:47 PM, William G. wrote:

Greg W. wrote:

I know I’ve bumped into this before but all the descriptions made
it sound like it was designed to execute Ruby syntax inside Java
(the opposite of my task).

It is. The point being made was that, once you’re executing Ruby
inside
the JVM, you can then call out to other things (java code) inside
the same
JVM.

See, now for whatever reason, this is one of those things that my
brain is refusing to grab a hold of and just “get.”

I can understand running Ruby inside Java. Easy concept. However, I
don’t want to run Ruby inside Java, I just want to pass some data
from Ruby to Java. Have Java do some things, and then pass some data
back to Ruby. Without using web services. Once inside Java, the code
will be Java.

So, when you (and other descriptions I’ve read) say, “once you’re
executing Ruby inside the JVM,” my brain shuts down and says “but how
do I pass the params from the Ruby app into the Java app?” Either
there’s a step there being assumed that I’m not aware of, or there’s
an assumption that the whole app is actually running in a Java
container, and it uses some Ruby syntax in it so there’s no need to
write Java. That’s not what I’m trying to acheive.

Nevertheless, I’ll dig further into JRuby to understand it better.

BTW–I should clarify I am not a Java programmer, so indeed I could
very well be missing something a Java programmer would assume and
understand right away. I’m just the poor slob that has to determine
from a high level whether and how this “bridge” would be implemented
so we can avoid a JSP front end.

Enterprise Integration with Ruby has quite a bit on
interoperability.
In particular, the discussion of RMI is probably relevant.
http://media.pragprog.com/titles/fr_eir/contents.pdf

Indeed. Ordered it. Whether or not it addresses this very task, it
looks worth having around. Thanks.

– gw

On 8/15/06, William G. [email protected] wrote:

Let me say it a slightly different way.

  1. Java is a programming language.
  2. The JVM (java virtual machine) is a platform for executing “bytecode”
  3. Java compiles into bytecode, which then gets executed on the JVM.
  4. JRuby is a Java application which compiles Ruby to bytecode which can
    be executed on a JVM (NOT using the standard ruby binaries).

Just so there’s no confusion here…JRuby does not compile Ruby to
bytecode
(yet!). It’s currently a pure interpreter, like normal Ruby, but a
compiler
to Java bytecode is in the works (and performs very well so far!).

  1. The way you run Ruby applications “inside Java” is to use JRuby as a

On Aug 15, 2006, at 3:59 PM, William G. wrote:

or there’s an assumption that the whole app is actually running in

  1. JRuby is a Java application which compiles Ruby to bytecode
    which can
    be executed on a JVM (NOT using the standard ruby binaries).

That I understood.

  1. The way you run Ruby applications “inside Java” is to use JRuby
    as a
    compiler, which compiles the Ruby code to bytecode, which the
    JVM then
    executes.

That’s the connection I was missing – dynamically passing Ruby code
to the JVM. I was looking at it quite differently.

System.out.println(“Hello Java in Ruby!”)

That’s Ruby! JRuby can compile it and it will run in the JVM, but
it’s Ruby.

But it’s ruby code that requires ‘java’ and then calls to a java
method
(println, on System.out). And you have to be running your entire
application
on a JVM (with JRuby) to make it work.

OK, by “entire” application… would you diagram the environment that
Charles’ code is executing in to be like a) or b)

(a)


| Ruby WebApp |—>| JVM w/ JRuby |


(b)

| JVM |
| --------------- ----------- |
| | Ruby WebApp |–>| JRuby | |

--------------- -----------

And, one last (probably painfully obvious) thing… any result coming
from the JRuby environment can be captured by a typical Ruby
assignment, yeah? Data type matching just has to be something
interchangable. Perhaps a delimited list string coming from Java,
which could then be recast as a Ruby array. Anyway, I’m sure that’s
covered in the JRuby docs.

Guys, I appreciate the hand holding. If I end up latching onto Ruby/
Rails, I promise to be a contributor (evidence: http://
www.pageblocks.org, http://www.araelium.com).

– greg willits

On 8/15/06, Greg W. [email protected] wrote:


| JVM |
| --------------- ----------- |
| | Ruby WebApp |–>| JRuby | |

--------------- -----------

It would be (b) for what you’re doing. The Java bridges would be more
like
A, but in the same process and a web service solution would be like A
but in
separate processes.

And, one last (probably painfully obvious) thing… any result coming

from the JRuby environment can be captured by a typical Ruby
assignment, yeah? Data type matching just has to be something
interchangable. Perhaps a delimited list string coming from Java,
which could then be recast as a Ruby array. Anyway, I’m sure that’s
covered in the JRuby docs.

Yes, basically any result returned from Java will look and feel just
like
Ruby. Basic types like Strings will just map to Ruby strings, and so on.
Complex types will just map to what looks and acts like a Ruby type. The
translation is pretty seamless, though there are edge cases that don’t
map
perfectly (as you might expect with two fairly different languages).

If you were using JRuby to run a Rails app and call this other app/API
you’re talking about, all you’d really need to do is the following lines
in
some file (probably your Rails controller:

require ‘java’
include_class “some.api.EntryPoint”

and then in whatever action you’re dealing with that needs to access
that
service, you’d simply call

@search_results = EntryPoint.doSomeMagicSearch(my_criteria)…

or whatever’s necessary to start that API up.

A few caveats if you go down this path:

  • Rails support isn’t perfect, but works for simple apps. It’s getting
    better every day and it’s one of our two top priorities.
  • JRuby is a bit slower than regular Ruby right now, but this is the
    other
    top priority. That said, a Rails app in production mode runs pretty darn
    well, returning pages and handling database hits almost instantly.
  • You won’t be able to use the ActiveRecord adapters shipped with core
    Rails, but there’s an adapter that wraps Java’s builtin support for
    databases. It works very well, but there’s a little more configuration
    involved.

Of course, you won’t be alone :slight_smile: We’re keen to support anyone looking to
try
Rails under JRuby, and this is exactly the kind of scenario that’s a
compelling reason do do it.

On Aug 15, 2006, at 6:53 PM, Charles O Nutter wrote:


| JVM |
| --------------- ----------- |
| | Ruby WebApp |–>| JRuby | |

--------------- -----------

It would be (b) for what you’re doing. The Java bridges would be
more like A…

A few caveats if you go down this path…

Thanks Charles. After a little more digging, I now see I’m talking to
the go-to guy for JRuby :wink:

At this point, I have the next level of clarity I needed, and I
suspect I can take the next dose of questions with some of my app
specifics offline.

Thanks a bunch everyone.

– gw

If you do take them offline, please post a summary of what you learned.

Bill

Greg W. wrote:
At this point, I have the next level of clarity I needed, and I
suspect I can take the next dose of questions with some of my app
specifics offline.
Thanks a bunch everyone.

William G. wrote:
If you do take them offline, please post a summary of what you
learned.

Will do.

At this point I have to decide whether the application is
predominantly a Rails application augmented by Java, or whether it is
a Java application with a Rails front end.

Until a week ago, I thought of it as a Rails app augmented by Java.
Since then a couple major factors have caused me to see it more as a
set of Java engines connected by a thin Rails GUI.

I was hoping to avoid having a Java container at all (and thus my
preference for something more bridge-like), but considering the state
of affairs there, the best architecture may yet be something like
JRuby where access to Java will better serve the heavy cores of the
application performance needs.

But, honestly, it does make me think that if the GUI is that “thin,”
a full JSP app may be more efficient after all.

Much reading and thinking to still do.

– gw

Hi,

can you please guide me as to how were you able to call java classes
from rails app using JRuby?

Thanks.

Greg W. wrote:

Greg W. wrote:
At this point, I have the next level of clarity I needed, and I
suspect I can take the next dose of questions with some of my app
specifics offline.
Thanks a bunch everyone.

William G. wrote:
If you do take them offline, please post a summary of what you
learned.

Will do.

At this point I have to decide whether the application is
predominantly a Rails application augmented by Java, or whether it is
a Java application with a Rails front end.

Until a week ago, I thought of it as a Rails app augmented by Java.
Since then a couple major factors have caused me to see it more as a
set of Java engines connected by a thin Rails GUI.

I was hoping to avoid having a Java container at all (and thus my
preference for something more bridge-like), but considering the state
of affairs there, the best architecture may yet be something like
JRuby where access to Java will better serve the heavy cores of the
application performance needs.

But, honestly, it does make me think that if the GUI is that “thin,”
a full JSP app may be more efficient after all.

Much reading and thinking to still do.

– gw

If you’re interested in going the bridge route, I’ve used Jrb (Java-Ruby
bridge, see: http://arton.no-ip.info/collabo/backyard/?RubyJavaBridge)
to successfully use both JVM built-ins as well as talk to a 3rd party
API (JExcelAPI).

See Xalan with Ruby (either command line or via Jrb)? - Ruby - Ruby-Forum for some code examples of how
you can us Jrb.

Feel free to email me at weyus at att dot net with questions. I’ve
found Jrb to work quite well.

Wes