(Crossposting note: I have asked this question one week ago at the JRuby mailing list, but didn't get any answer yet).
I have a jar file provided by someone else, no access to the source code. The jar file is in lib/other/appl.jar, the class is named Appl, and the package is com.abc.xyz
I would like to instantiate an Appl object from the JRuby irb, jirb_swing_ex.
(Of course my problem applies not only to jirb, but to running JRuby programs in general, but I explain it in the way I'm using it right now, just in case there are some peculiarities in Jirb which need special treatment).
THIS is the way it DOES work:
(1) Invoke jirb by:
java -jar jr/jruby-complete-1.7.27 jb/jirb_swing_ex
(2) Put the directory with the jar file into the load path:
$: << 'lib/other'
(3) Load the jar file
require 'appl.jar'
(4) Import the class
java_import com.abc.xyz.Appl
(5) Create the object
x = Appl.new
As I said, this works, and I can live with it if necessary, but I would prefer a simpler approach:
NOW TO MY QUESTION: Instead of fiddling around with load path and doing a require
for the Jar file, I thought I could let Java already include the jar file. This is what I have tried:
java -cp lib/other/appl.jar -jar jr/jruby-complete-1.7.27 jb/jirb_swing_ex
The problem is: How can I get at my object? If I just use the class name com.abc.xyz.Appl, JRuby complains that the class not found (NameError: missing class name).
BTW, I have also tried forward slashes (since I'm on Windows), i.e.
java -cp lib\other\appl.jar -jar jr\jruby-complete-1.7.27 jb\jirb_swing_ex
but the same effect. I had expected that, having appl.jar in my class path, would make the classes available somehow, but I seem to miss something.
jirb
or jirb_swing
with custom class pathjirb
and jirb_swing
will use the value of JRUBY_CP
environment variable (if present) to extend class path given to Java command line.
Example with commons-lang3 library taken from my local maven repository, using bash on Linux or macOS:
$ export JRUBY_CP=${HOME}/.m2/repository/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar
$ jirb
irb(main):001:0> org.apache.commons.lang3.mutable.MutableBoolean.new
=> #<Java::OrgApacheCommonsLang3Mutable::MutableBoolean:0x7c24b813>
To run a JRuby program that uses a third-party java library, this won't work:
java -cp lib/other/appl.jar -jar jr/jruby-complete-1.7.27 ...
You must use either -jar
or -cp
, you can't combine the two.
From java
man page:
When you use this option [-jar], the JAR file is the source of all user classes, and other user class path settings are ignored.
In addition, you need to pass the main Java class, which is org.jruby.Main
, and that class needs arguments: either a path to a Ruby script, or other command line arguments such as -e 'puts 2+2'
.
So the command line structure is the following:
# Run script file:
java -cp path/to/jruby.jar:other/custom.jar org.jruby.Main path/to/script
# Run simple one-line Ruby program
java -cp path/to/jruby.jar:other/custom.jar org.jruby.Main -e 'some ruby here'
(on Windows please use ;
instead of :
as separator)
Actual example with same commons-lang3 library & OS:
$ alias myjruby="java -cp ${JRUBY_HOME}/lib/jruby.jar:${HOME}/.m2/repository/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar org.jruby.Main"
# Verifying base jruby code works with that:
$ myjruby -e 'puts 2+2'
4
# Now verifying it can use my 3rd-party lib:
$ myjruby -e 'puts org.apache.commons.lang3.mutable.MutableBoolean.new'
false