rjb is a bridge software. It connects Ruby and Java.
ASR-1.8.5.1 also contains rjb-1.0.1 binary
Known Restriction: Rjb only supports JVM's main thread. At least you can never invoke Ruby's GC from JVM's worker thread, it causes something bad or die.
For example, if you use Linux with Sun j2se, you need to set LD_LIBRARY_PATH points j2se shared objects explicitly.
sh, bash:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/i386:$JAVA_HOME/jre/lib/i386/client
csh, tcsh:
setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/i386:$JAVA_HOME/jre/lib/i386/client
Both LD_LIBRARY_PATH and JAVA_HOME setting required in environment.rb file of RoR.
Setting them in the apache conf didn't seem to work.
This tip was contributed by Ruban Phukan, Thanks Ruban.
Using Apache + FastCGI, if you set JAVA_HOME and LD_LIBRARY_PATH in the FastCGI module configuration file using the -initial-env option, like so:
-initial-env RAILS_ENV=production \
-initial-env JAVA_HOME=/usr/java/jdk1.5.0_09 \
-initial-env LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/i386
then RJB will work without specifying these environment variables in environment.rb.
This tip was contributed by Wes Gamble, Thanks Wes.
you never need to set LD_LIBRARY_PATH, because they can be loaded and bound into the process dynamically. (it may cause any vulnelability ?)
At this time, rjb test.rb fails test_underscored_constant, but I can't figure out what's wrong.
Please ignore this issue (I'm continuously working).
require 'rjb'
Rjb::load(classpath = '.', jvmargs=[])
classpath is a client supplied runtime classpath. Rjb appends this string before ENV['CLASSPATH'] using PATH_SEP character.
jvmargs is a string array. Its elements are the jvm arguments.
ex)
Rjb::load(nil, ['-verbose:gc', '-Dfoo.bar=FooBar'])
If you don't need to specify both classpathes and JVM argments, then you can skip to call Rjb::load.
str = Rjb::import('java.lang.String') # import String class into the varibale 'str'
After this call, the variabe 'str' contains java.lang.String class.
instance = str.new
This means that
String instance = new String();
For java.lang.String, you'd like to call the constructor with some arguments like
String instance = new String("hiki is a wiki engine");
// in Java, this call was nonesence because String is imutable...
With rjb, you need to specify type informations for theses overloaded methods.
instance = str.new_with_sig('Ljava.lang.String;', 'hiki is a wiki engine')
| type name | encoded name |
| boolean | Z |
| byte | B |
| char | C |
| class or interface | Lclassname; |
| double | D |
| float | F |
| int | I |
| long | J |
| short | S |
more example
irb(main):001:0> require 'rjb'
=> true
irb(main):002:0> Str = Rjb::import('java.lang.String')
=> #<Rjb::Java_lang_String:0x2c64ba0>
irb(main):003:0> s = Str.new_with_sig('[BLjava.lang.String;', [48, 49, 50], 'Windows-31j')
=> #<#<Class:0x2c6a2b8>:0x2c5c3f8>
irb(main):004:0> p s.toString
"012"
=> nil
irb(main):005:0>
in Java
String instance2 = instance.replaceAll("hiki", "rwiki");
in rjb
s = instance.replaceAll('hiki', 'rwiki')
in rjb, returned String coerces to ruby's String, not java.lang.String instance.
Rjb inspect type of arguments, and then decides which method to be called. But it's not complete (suppose the case; if there are three methods like void foo(int), void foo(short), void foo(long), and the argument is 30), in this case you need to call with obj#_invoke as
instance2 = instance._invoke('replaceAll', 'Ljava.lang.String;Ljava.lang.String;', 'hiki, 'rwiki')
>ruby -rrjb -e "Rjb::import('java.lang.System').out.println('Just Another Ruby Hacker')"
Just Another Ruby Hacker
>
require 'rjb'
pnt = Rjb::import('java.awt.Point')
p = pnt.new(0, 0)
p.y = 80
puts "x=#{p.x}, y=#{p.y}"
=>
x=0, y=80
You can bind Ruby object to Java interface as long as the object has responsable to respond the method call from Java world.
class Comparable
def initialize(val)
@value = val
end
def compareTo(oponent)
return @value - oponent.to_i
end
end
cp = Comparable.new(3)
cp = Rjb::bind(cp, 'java.lang.Comparable')
You can throw java exception from the bounded object.
class Iterator
def hasNext()
true
end
def next()
Rjb::throw('java.util.NoSuchElementException', 'test exception')
end
end
This code throws NoSuchElementException? with a message 'test exception' while the caller calls Iterator#next.
Rjb adds a method named _classname for each instance. This method returns the name of its class.
ex)
require 'rjb'
out = Rjb::import('java.lang.System').out
p out._classname
out.println('jarh')
result)
"java.io.PrintStream" jarh
Couldn't you help to correct English in this page ?