如何从Ruby 1.8或1.9调用Java API

3
我有一段工作中的JRuby代码(从Keith's Blog中窃取),它包装了SAXON xslt处理器API。

现在,我想知道我是否可以以Ruby框架来包装相同的API?

请告诉我这个问题是否没有意义或者是否有改进的空间。
这是所需API的Java文档参考。
这是我正在使用的JRuby代码:
require 'java'
module JXslt
  include_class "javax.xml.transform.TransformerFactory"
  include_class "javax.xml.transform.Transformer"
  include_class "javax.xml.transform.stream.StreamSource"
  include_class "javax.xml.transform.stream.StreamResult"
  include_class "java.lang.System"

  class XsltProcessor
    def transform(xslt,infile,outfile)
      transformer = @tf.newTransformer(StreamSource.new(xslt))
      transformer.transform(StreamSource.new(infile), StreamResult.new(outfile))
    end
  end # XsltProcessor
  class Saxon < XsltProcessor
    TRANSFORMER_FACTORY_IMPL = "net.sf.saxon.TransformerFactoryImpl"
    def initialize
      System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_IMPL)
      @tf = TransformerFactory.newInstance
    end
  end
end 

通过在Ruby框架中封装相同的API,您的意思是不使用JRuby吗?这是不可能的,除非您深入研究C代码并使用JVM C API从C调用Java类。 - Maurício Linhares
@Mauricio 我的意思是:我想使用相同的模块/类来使用Ruby解释器(而不是JRuby),或者以相同的方式包装API,以便可以在Ruby中使用。这可行吗?我需要深入研究C代码吗? - Emiliano Poggi
@Mauricio 这个难度大吗?你认为针对这个问题设置“赏金”会有人回答吗? - Emiliano Poggi
1
这并不简单,因为你需要从 Ruby 中调用 C 代码,然后再从 C 代码中调用 Java 代码来执行你想要执行的任何操作。这里有一篇关于如何从 C 代码中调用 Java 的文章 -> http://www.codeproject.com/KB/cpp/CJniJava.aspx - 如果我是你,我肯定会选择 JRuby 而不是这样做。 - Maurício Linhares
@Mauricio 谢谢,我正考虑使用 Ruby,因为 Ruby 本身没有任何类似的类。我会看一下那篇文章。 - Emiliano Poggi
不,没有现成的方法。你需要编写一个C库来调用Java类,然后在Ruby中编写一个包装器来调用你构建的这个C库。你可以使用FFI完成这个过程 - https://github.com/ffi/ffi - Maurício Linhares
1个回答

7

如上所述,您无法直接从Ruby运行时执行此操作,从Ruby调用Java需要您使用JRuby或使用C / C ++ JVM API间接调用Java代码。

第一种选择可能是使用Ruby Java Bridge,它会为您完成大部分繁重的工作(它作为Ruby-to-C-to-Java包装器运行)。

如果RJB对您不起作用,您还可以使用C中的JVM API(此处有示例)直接构建包装器,然后您可以使用FFI从Ruby调用它。

但是,除非您真的需要使用C-Ruby(MRI),否则我强烈建议您避免上述任何方法,只需使用JRuby即可,因为深入研究本机代码将导致可能的段错误、内存管理问题,并且上述所有选项都强制您在单个线程中运行,而使用JRuby可以构建多线程解决方案。


谢谢,我很感激你的建议。 - Emiliano Poggi
由于我没有尝试过且没有足够的经验来确认,因此无法提供真正的反馈。不过听起来是正确的(而且不容易:(),也没有人提供任何其他选择。无论如何,我将遵循您最后的建议,继续使用jruby。谢谢。 - Emiliano Poggi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接