从(例如)JRuby irb 中访问 jar 文件中定义的 类?

Access classes defined in a jar file, from within (for instance) JRuby irb?

(交叉贴:我一周前在 JRuby 邮件列表上问过这个问题,但还没有得到任何答复)。

我有一个别人提供的jar文件,无法访问源代码。 jar文件在lib/other/appl.jar中,class名为Appl,包为com.abc.xyz

我想从 JRuby irb 实例化一个 Appl 对象,jirb_swing_ex。

(当然,我的问题不仅适用于 jirb,而且适用于一般的 运行 JRuby 程序,但我以我现在使用它的方式解释它,以防万一有一些特殊之处在需要特殊处理的 Jirb 中)。

这就是它的工作方式:

(1) 通过以下方式调用 jirb:

java -jar jr/jruby-complete-1.7.27 jb/jirb_swing_ex

(2)将jar文件所在目录放入加载路径:

$: << 'lib/other'

(3) 加载jar文件

require 'appl.jar'

(4) 导入 class

java_import com.abc.xyz.Appl

(5) 创建对象

x = Appl.new

正如我所说,这很有效,如果需要我可以接受,但我更喜欢更简单的方法:

现在回答我的问题:与其摆弄加载路径并对 Jar 文件执行 require,我想我可以让 Java已经包含了 jar 文件。这是我试过的:

java -cp lib/other/appl.jar -jar jr/jruby-complete-1.7.27 jb/jirb_swing_ex

问题是:我怎样才能得到我的对象?如果我只使用 class 名称 com.abc.xyz.Appl,JRuby 会抱怨 class not found (NameError: missing class 名字)。

顺便说一句,我也试过正斜杠(因为我在Windows),即

java -cp lib\other\appl.jar -jar jr\jruby-complete-1.7.27 jb\jirb_swing_ex

但效果一样。我原以为 appl.jar 在我的 class 路径中,会使 classes 以某种方式可用,但我似乎错过了一些东西。

运行 jirbjirb_swing 自定义 class 路径

jirbjirb_swing 将使用 JRUBY_CP 环境变量(如果存在)的值来扩展给定 Java 命令行的 class 路径。

commons-lang3 库的示例取自我的本地 maven 存储库,在 Linux 或 macOS:

上使用 bash
$ 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>

运行 JRuby 具有自定义 class 路径的程序

对于使用第三方 java 库的 运行 JRuby 程序,这将不起作用:

java -cp lib/other/appl.jar -jar jr/jruby-complete-1.7.27 ...

你必须使用 either -jar or -cp, you can't combine the two.
来自 java 手册页:

When you use this option [-jar], the JAR file is the source of all user classes, and other user class path settings are ignored.

此外,您需要传递主要的 Java class,即 org.jruby.Main,而 class 需要参数:要么是 [= 的路径61=] 脚本,或其他命令行参数,例如 -e 'puts 2+2'.

所以命令行结构如下:

# 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'

(在 Windows 上请使用 ; 而不是 : 作为分隔符)

具有相同 commons-lang3 库的实际示例 & 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