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