如何在Ruby 1.8或1.9调用Java API [英] How to call Java API from Ruby 1.8 or 1.9
问题描述
我这个的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屋!