RjbMechanism
Rjb - How It Works
Rjb is a JVM host program
Rjb dynamically loads the JVM library in process memory space and creates one virtual machine for the service, then uses it until Rjb::unload is called. So if you call Java objects as many as you need to, the Java JIT compiler will optimize more and more.
Rjb creates proxy classes and instances
As the chart above, Rjb creates proxy objects one by one for bridging.
- the script call Rjb::import('Foo.Foo')
- Rjb calls FindClass? method to find 'Foo.Foo'. JVM returns the Class object or at first time ClassLoader loads the class and returns it.
- Rjb reads metadata (methods and fields informations) from the Class object, then creates a proxy class and stores metadata in it.
- the script call 'new' on the proxy class for instantiating Java object.
- the proxy class calls Java Class object fro creating Java Object.
- the proxy class creates a proxy object and stores Java Object's reference and metadatas.
- the script gets the proxy object.
- the script calls the method on the proxy object.
- the proxy object coerces the arguments to Java data types and calls the method on the Java Object.
- (not there) the proxy object coereces the returned value and returns to the script.
Known restrictions
GC and threading issues
In this clause, 'thread' means OS's native thread. Not means the ruby thread. In fact ruby thread doesn't map to the OS native thread. In other words, All of the ruby threads run in the OS's main thread.
You can't create Ruby object in the thread other than the main thread. If you make it, in worst case, the process is crushed.
You may know the implementation of ruby's thread is fibers in the OS level. Ruby only knows one main thread and only its stack, so GC only marks and sweeps a range of the main thread's stack if GC is invoked in the main thread. That can harm if another native thread creates Ruby objects and keeps them in the thread's stack. Vice versa if GC is invoked in the thread other than the main thread, GC can't find the stack top (maybe it's far from thread boundary), and touches the gap of the allocated memory. It causes a segmentation violation.
So it's very dangerous to call back ruby's object from the Java's worker thread. For example Swing/AWT event listener.
OS specific issues
OS X
In OS X's Java implementation, AWT/Swing classes must load in the worker thread (other than the main thread). It's defined by design. But the process is dominated by Ruby, and it can't create native threads, so Rjb can't import AWT/Swing classes.
Linux (version 2.4.x)
In Linux's Java implementation, AWT/Swing heavily depends on signals. Ruby and Java's signal usage are conflicted (at least I watched the behaviour of the issues). So no meaningful widgets are displayed correctly.
Keyword(s):
References:[RubyJavaBridge]