Ruby/Java integration through JNI: working implementation

I’m sure you will let the list know when you have something you want to
show to the world, but I just wanted to say that it sounds very
interesting and useful! Looking forward to hearing more.

All the best,

Jon

···

-----Original Message-----
From: Mauricio Fernandez [mailto:batsman.geo@yahoo.com]
Sent: 25 June 2003 14:29
To: ruby-talk ML
Subject: Ruby/Java integration through JNI: working implementation

This is the idea that popped out during the last discussion in Euruko03.
(sorry, don’t remember the name of the guy who exposed it :slight_smile:

It has taken me a little bit more than I first thought (the Chinese kept
me busy :), but 3 days later I have the first working code.

I have created a straight-forward mapping for most of the
JNI API, which becomes available as a Ruby extension. This
allows the use of the low-level interface specified in
Oracle Java Technologies | Oracle. This part is
written in C (around 4000 LOCs at the moment).

I have built a simple reflection system that maps Java classes to Ruby
space, by using the reflection API to get information on all the
available
methods. At the moment it is written in Ruby but it should probably be
coded in C for speed (this can be done later w/o any problem) and allows
to call methods transparently as if they were implemented in Ruby.

At the moment, the following is working:

  • creating objects and manipulating native types
  • static methods w/ arbitrary parameters and any return value (native
    or
    object types)
  • methods " " " "
  • Java objects arrays
  • non virtual method calls
  • method overloading (dispatching is performed depending on arg types)
  • seamless conversion of Ruby String and Numeric types to the required
    Java types according to method signatures

Things I have to work on:

  • think about Java exceptions: map them to Ruby or signal them somehow?
  • dynamic definition of Java classes and adding native methods at
    run-time (for instance to call Ruby Procs in callbacks)
  • more automated conversions: Arrays to Java’s type and vice-versa
  • wrap Java’s reflection API completely, providing convenient metaclass
    abstractions & such
  • add more methods to the wrapped Java objects to integrate them better
    w/ Ruby
  • cover more code w/ unit tests (esp. the reflection part)

This is real example of what I’m doing:

Given Simple.java:

public class Simple {
public String doStuff(String a) {
return “I was called with argument "” + a.toString() + “"” ;
}

public String doStuff(String a, String b) {
return a + b;
}

public boolean compareStrings(String a, String b) {
System.out.println("I was passed " + a + " and " + b);
return a.equals(b);
}

public int compare2(String a, String b) {
System.out.println("I was passed " + a + " and " + b);
return a.compareTo(b);
}

public int sum(String a, String b) {
System.out.println(“Adding " + a + " and " + b + " (inside
Java!!!)”);
int i = Integer.parseInt(a) + Integer.parseInt(b);
System.out.println("The result will be: " + i);
return i;
}
}

I can instantiate the Java object and access its methods from Ruby as
follows:

require ‘reflect’
require ‘rjni’

vm = RJNI::JVM.new “-cp .”
reflector = RJNI::Reflect.new(vm)
sclass = reflector[“Simple”]
o = sclass.new_object
r = o.doStuff(“foo passed from Ruby!!!”)
puts “Result: #{r}”
r = o.doStuff("hello, ", “world!”)
puts “Result: #{r}”
r = o.compareStrings(“ruby”,“matz”)
puts “Result: #{r.to_b}”
r = o.compareStrings(“matz”,“matz”)
puts “Result: #{r.to_b}”
r = o.compare2(“ruby”,“matz”)
puts “Result: #{r.to_i}”
r = o.compare2(“matz”,“matz”)
puts “Result: #{r.to_i}”
r = o.sum(“1”, “1”)
puts “Result: #{r.to_i}”

Result:

batsman@tux-chan:~/src/rjni$
LD_LIBRARY_PATH=/usr/local/java/j2sdk1.4.1/jre/lib/i386/:/usr/local/java
/j2sdk1.4.1/jre/lib/i386/client ruby tc_reflect.rb
Result: I was called with argument “foo passed from Ruby!!!”
Result: hello, world!
I was passed ruby and matz
Result: false
I was passed matz and matz
Result: true
I was passed ruby and matz
Result: 5
I was passed matz and matz
Result: 0
Adding 1 and 1 (inside Java!!!)
The result will be: 2
Result: 2

The code is right now in a state of flux as I am quickly adding
functionality but I am going through quite fast so I should be able to
release something soon.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

need help: my first packet to my provider gets lost :frowning:
sel: dont send the first one, start with #2

  • netgod is kidding

This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk



This message has been checked for all known viruses by Star Internet delivered
through the MessageLabs Virus Control Centre. For further information visit
http://www.star.net.uk/stats.asp


Any views or personal opinions expressed within this email may not be those of Talis Information Ltd.
The content of this email message and any files that may be attached are confidential, and for the usage of the intended recipient only. If you are not the intended recipient, then please return this message to the sender and delete it. Any use of this e-mail by an unauthorised recipient is prohibited.