如何在Ruby 1.8或1.9调用Java API [英] How to call Java API from Ruby 1.8 or 1.9

查看:277
本文介绍了如何在Ruby 1.8或1.9调用Java API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这个的JRuby 工作的code(从的 Keith的博客),它包装的SAXON XSLT处理器API。


  

现在,我不知道我是否能够以及如何我包装在Ruby框架,相同的API?


请告诉我,如果这个问题是无义或如果它可以以某种方式加以改进。

这是为想要的 API

这是JRuby的code我使用的是:

 要求'的Java
模块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中的  类XSLTProcessor中
    高清转换(XSLT,INFILE,OUTFILE)
      变压器= @ tf.newTransformer(StreamSource.new(XSLT))
      transformer.transform(StreamSource.new(INFILE),StreamResult.new(OUTFILE))
    结束
  结束#XSLTProcessor中
  类撒克逊< XSLTProcessor中
    TRANSFORMER_FACTORY_IMPL =net.sf.saxon.TransformerFactoryImpl
    高清初始化
      System.setProperty(javax.xml.transform.TransformerFactory中的TRANSFORMER_FACTORY_IMPL)
      @tf = TransformerFactory.newInstance
    结束
  结束
结束


解决方案

如上评论,你不能直接从Ruby运行时做到这一点,调用Java从红宝石需要你无论是在JRuby和Java的间接使用C调用/ C ++ API的JVM,使您可以从C调用Java code。

第一个选项是可能使用红宝石的Java桥,做最繁重的工作适合你(它作为一个Ruby到-C到Java包装)。

如果RJB不会为你工作,你也可以直接使用在C JVM API(的例如这里),然后你可以在Ruby使用称呼它 FFI

但除非你真的需要使用C-红宝石(MRI),我将非常建议你避免任何上述方法中,只使用JRuby中,作为深入研究本地code会导致可能的段错误,内存管理问题和力以上所有的选项,你要在一个线程中运行,而你可以通过使用JRuby构建一个多线程的解决方案。

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 

解决方案

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.

这篇关于如何在Ruby 1.8或1.9调用Java API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆