首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > Ruby Rails >

[通译] JRuby class loader by example

2012-12-27 
[翻译] JRuby class loader by example大家都知道,JRuby可以用 require 来装载 jar 文件,但是似乎很少有人

[翻译] JRuby class loader by example

大家都知道,JRuby可以用 require 来装载 jar 文件,但是似乎很少有人知道有另外两种方法可以完成同样的事情,也很少有人知道(JRuby)底层是如何做的。JRuby官方的 wiki 页面 包含了一组例子以帮助大家学习这些,不过,也许还可以更进一步......

?

如前所述,在你的ruby应用中装载java类的首要方法是 require 。它的工作方式与对 ruby 文件的装载类似,只是装载目标变成了jar文件,可以用类似下面的代码装载(jar文件中被打包的)java类:

?

?

require 'java'require 'hello_world.jar'

?

然而,这种方式只是让我们装载jar文件,它不能用于装载存放众多类文件的classes目录。

?

第二种方式是使用 $CLASSPATH 这个全局变量,这个方式很类似我们在 $LOADPATH 全局变量上增加或者去除路径。这个方法的好处是可以添加一个存放类文件的目录,你可以试试下面的代码

?

require 'java'$CLASSPATH << 'hello_world.jar'$CLASSPATH << 'hello_world_directory'

?

如果我们想深入了解这两种方法(require和$CLASSPATH),我们将发现,require实际上最终还是把我们要装载的jar文件添加到了 $CLASSPATH 上:

?

?

$ irbjruby-1.6.0.RC2 :001 > require 'java' => truejruby-1.6.0.RC2 :002 > require '/Users/david/dev/jruby/lib/jruby.jar' => truejruby-1.6.0.RC2 :003 > $CLASSPATH => ["file:/Users/david/dev/jruby/lib/jruby.jar"]

?

第三种方法可能是最少被人所知的,在我们使用jruby的环境时,我们可以访问一个叫做JRuby的常量,而在这个常量中,有一些东西可以帮助程序员访问JRuby的运行时环境,在这里,我们能够接触到JRuby进行java类装载的 class loader:? JRuby.runtime.jruby_class_loader ,代码示例如下:

?

?

require 'java'F = java.io.Fileclass_loader = JRuby.runtime.jruby_class_loaderclass_loader.add_url(F.new('hello_world_directory').to_url)class_loader.add_url(F.new('hello_world.jar').to_url)

?

看看这里的代码,我们可以发现,当我们将一些东西添加到 $CLASSPATH 常量上去的时候,我们实际上是在将这些东西添加进JRuby的class loader:

?

@JRubyMethod(name = {"append", "<<"}, required = 1)public IRubyObject append(IRubyObject obj) {    String ss = obj.convertToString().toString();    try {        URL url = getURL(ss);        getRuntime().getJRubyClassLoader().addURL(url);    } catch (MalformedURLException mue) {        throw getRuntime().newArgumentError(mue.getLocalizedMessage());    }    return this;}
?

好了,现在的问题是,我们应该使用哪种方式(去装载java类)呢?对于日常的情况,最好的方式显然是 require——我们使用的大多数java 代码都是被打包成一个jar文件的,而且,这也是我们都知道的语法。如果我们需要的java类文件存放在目录中或者我们有一些很特殊的场景,可能更好的选择是设置 $CLASSPATH ,它也能满足我们的需要,而且我们还不必与url和java方言(指class loader这种很java的东西)打交道,同时,这也是一个我们都知道的语法。最后,第三个方案适合那些需要清晰界定 class loader 的场景中。例如,在Trinidad中,我就用了这个方案,这里,每一个被部署的应用需要装载自己的jar文件,第三个方案可以让我针对每个应用建立新的class loader并保证这些class loader之间是完全隔离的。

?

热点排行