如何从 Ruby 1.8 或 1.9 调用 Java API

发布于 2024-12-02 10:14:09 字数 1200 浏览 7 评论 0原文

我有这个JRuby工作代码(从Keith 的博客),它包装了 SAXON xslt 处理器 API。

现在,我想知道我是否可以以及如何在 Ruby 框架中封装相同的 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 

I've this JRuby working code (stolen from Keith's Blog), which wraps the SAXON xslt processor API.

Now, I wonder whether I can and how can I wrap the same API in Ruby framework?

Please tell me if this question is non-sense or if it can be improved in some way.

This is the java doc reference for the wanted API.

And this is the JRuby code I'm using:

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 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

GRAY°灰色天空 2024-12-09 10:14:09

,从 Ruby 调用 Java 需要您使用 JRuby 或使用允许您从 C 调用 Java 代码的 C/C++ JVM API 间接调用 Java。

如上所述,您不能直接从 Ruby 运行时执行此操作 可能正在使用 Ruby Java Bridge 来为您完成大部分繁重的工作(它的功能就像一个 Ruby-to- C 到 Java包装纸)。

如果 RJB 不适合您,您还可以使用 C 语言中的 JVM API 直接构建包装器 ( 示例在这里),然后您可以使用 FFI 从 Ruby 调用它。

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

As commented above, you can not do this directly from the Ruby runtime, calling Java from Ruby requires you to be either on JRuby or call Java indirectly using the C/C++ JVM API that allows you to call Java code from C.

The first option is possibly using Ruby Java Bridge that does most of the heavy lifting for you (it functions as a Ruby-to-C-to-Java wrapper).

If RJB doesn't work for you, you can also build your wrapper directly by using the JVM API in C ( example here ) and then you could call it from Ruby using FFI.

But unless you really need to use the C-Ruby (MRI) I would greatly recommend you to avoid any of the approaches above and just use JRuby, as delving into native code will lead to possible segfaults, memory management issues and all options above force you to run in a single thread, while you could build a multi-threaded solution by using JRuby.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文