From: "J.Hawkesworth" Date: 2003-06-26T00:53:52+09:00 Subject: Re: 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 :) 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 http://java.sun.com/products/jdk/1.2/docs/guide/jni/. 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 :-( 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.