From: "Mauricio Fernández" Date: 2003-06-26T03:34:10+09:00 Subject: API for Ruby/Java integration through JNI (feedback needed!) OK, I'm going quite fast so I need now to decide how Java classes and objects are gonna work in Ruby. I'd appreciate some comments on what kind of mapping you'd like. At the moment I have the following classes: Low-level (won't change much) ============================= Implemented in C. * RJNI::Object low-level wrapper for a jobject (include jstring and others, including arrays). Accepts #to_s with the obvious semantics. * RJNI::Class idem for jclass. implements #to_s * RJNI::MethodID idem for jmethodID "" * RJNI::FieldID idem for jfieldID "" * RJNI::Primitive wrapper for native types (boolean, char, byte, short, int, long, float, double). Transform to Ruby w/ to.i, to_f and to_b. * RJNI::JVM object that represents the JVM and exposes the JNI interface This is the low-level part, nothing more than a simple mapping from JNI to Ruby. This allows to make use of JNI from Ruby, as in include RJNI vm = JVM.new "-cp ." klass = vm.find_class("Simple") constructor = vm.get_method_id(@klass, "", "()V") obj = vm.new_object(klass, constructor) methid = vm.get_method_id(klass, "doStuff", "()Llang/java/String;") # this gets the method id for method # String doStuff() str = vm.call_object_method(obj, methid) puts "Result: " + str.to_s As you can see, this is very low-level, just as JNI. This layer should expose all of JNI and allow you to do everything. It should be similar in spirit to Win32API. High-level (in a state of flux) ================================= This one is at the moment built upon the low-level layer, in Ruby. It could be done in C too, but I want to fix the API before. * Reflect::Class provides the list of instance methods * Reflect::Object understands and dispatches the appropriate Java methods This layer uses the JNI services of the former and transparently dispatches methods as needed via reflection. Right now it works as follows: reflector = Reflect.new vm # create the "reflector", only need one theklass = reflector["Simple"] object = theklass.new # mimic Ruby's object creation # from now on, can call methods on object and they are automatically # transformed into the appropriate vm.call_xxx_method as required # plus associated logic, depending on arguments and return value str = object.doStuff puts "Result: " + str.to_s Now, the things I need feedback on: * static methods: should they magically pop up in theklass, so that they work as in Class objects in Ruby? * should I provide #instance_methods and such? at the moment I've made #java_instance_methods that returns an Array with RJNI::Object objects that represent the methods. * should instance methods be directly invocable such as in the example above, or by doing object.send_java("doStuff", *args) or such? It is not as pretty, but OTOH this way there's no name collisions. * same as the latter w/ static methods (which would look like singleton methods of the Class object) Note that the method dispatching magic only works w/ Reflect::Object objects, so that RJNI::Object are lower-level and don't accept direct message passing (you have to use vm.call_xxx_method w/ them). Mapping the Reflection API ========================== a third possible API would be just mapping all of the Reflection, ie. creation something like RJNI::JavaReflection::{Class,Method,Field...}. it is only a little bit more convenient than using the JNI layer directly, but maybe somebody might appreciate it? Comments? If you're confused, here's some help :) Select one (mark your option w/ an X): ___ provide transparent mapping for everything, don't care about name clashes (or indicate solution for them) ___ do everything through send_java(method_name, *args) ___ forget about the "higher-level" thing and simply map the Reflection API 1:1 from Java to Ruby. -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com Do you mean to say that I can read mail with vi too? ;-) Didn't you know that? :r /var/spool/mail/jk -- debian-mentors